Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@
source, reserved metadata, sensitive-content, ordering-invariance, and shared
contract delegation tests for issue #404.

#### Enterprise semantic issue provider boundary

- Added runtime-checkable `EnterpriseAtomicIssueExtractor` and
`extract_enterprise_atomic_issues` as a provider-neutral, provider-SDK-free trust
boundary that returns the existing canonical `AtomicIssueRecord` contract.
- Added bounded exact source-packet replay, UTF-8 and Python code-point span
verification, fresh nested issue/evidence/counterevidence reconstruction,
deterministic ordering, duplicate and overlap rejection, and redacted provider
failures without retaining raw enterprise text.
- Added `StaticEnterpriseIssueExtractor` as an offline fixture and integration
adapter that performs no NLP, sentiment analysis, issue discovery, scoring,
ranking, utility, or causal arithmetic.
- Added deterministic order-invariance, all-assertion-kind preservation,
malicious provider, source mutation, span replay, subclass, privacy, prolific
collection, duplicate identity, overlap, and complete statement/branch coverage
tests for the next issue #404 workflow slice.

#### Accessible standalone essay facets-calibration artifacts

- Added `render_essay_facets_calibration_report_html`, which replay-verifies one governed `EssayFacetsCalibrationReport` and emits a deterministic, source-text-free, script-free standalone HTML audit artifact.
Expand Down
18 changes: 18 additions & 0 deletions docs/changelog.d/enterprise-semantic-issue-boundary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Enterprise semantic issue provider boundary

## Added

- Added runtime-checkable `EnterpriseAtomicIssueExtractor` and
`extract_enterprise_atomic_issues` as a provider-neutral, provider-SDK-free trust
boundary that returns the existing canonical `AtomicIssueRecord` contract.
- Added bounded exact source-packet replay, UTF-8 and Python code-point span
verification, fresh nested issue/evidence/counterevidence reconstruction,
deterministic ordering, duplicate and overlap rejection, and redacted provider
failures without retaining raw enterprise text.
- Added `StaticEnterpriseIssueExtractor` as an offline fixture and integration
adapter that performs no NLP, sentiment analysis, issue discovery, scoring,
ranking, utility, or causal arithmetic.
- Added deterministic order-invariance, all-assertion-kind preservation,
malicious provider, source mutation, span replay, subclass, privacy, prolific
collection, duplicate identity, overlap, and complete statement/branch coverage
tests for the next issue #404 workflow slice.
72 changes: 53 additions & 19 deletions docs/enterprise_issue_evidence_contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
`fast_mlsirm.scoring.enterprise_issue` provides the first provider-neutral domain
boundary for issue #404. The module stores content identities, exact source-span
offsets, epistemic roles, stakeholder perspectives, candidate-intervention
provenance, deterministic explicit values, criterion-level request provenance,
and governed criterion observations without retaining raw enterprise text.
provenance, deterministic explicit values, semantic issue proposals,
criterion-level request provenance, and governed criterion observations without
retaining raw enterprise text.

## Contract boundary

The initial slice deliberately separates five assertion kinds:
The domain deliberately separates five assertion kinds:

- directly stated facts;
- supported inferences;
- counterevidence;
- unresolved ambiguities;
- unresolved ambiguities; and
- stakeholder value judgments.

`EvidenceSpanRecord.to_evidence_reference()` compiles each span into the existing
Expand All @@ -22,11 +23,11 @@ supporting evidence, counterevidence maps to counter evidence, and ambiguities o
value judgments map to contextual evidence. This mapping does not convert an
inference into a fact or a preference into a materiality estimate.

The canonical records contain no source text, complaint text, lead notes,
customer names, or proposed-action text. Callers retain those values in an
authorized source system and pass SHA-256 content fingerprints plus offsets.
Sensitive metadata fields already prohibited by the shared scoring contract are
rejected here as well.
Canonical records contain no source text, complaint text, lead notes, customer
names, or proposed-action text. Callers retain those values in an authorized
source system and pass SHA-256 content fingerprints plus offsets. Sensitive
metadata fields already prohibited by the shared scoring contract are rejected
here as well.

## Deterministic explicit-value parser

Expand All @@ -40,7 +41,7 @@ that are already explicit in authorized source text. Its first grammar recognize
- positive recurrence counts per day, week, month, quarter, or year; and
- customer or account identifiers introduced by an explicit identifier label.

The parser verifies the transient text against the exact
The parser verifies transient text against the exact
`EnterpriseSourceRecord.source_content_fingerprint` and Python string character
count before extraction. Match offsets are Python Unicode-code-point indices,
which are appropriate for replaying slices of the same Python `str`; they are not
Expand Down Expand Up @@ -73,12 +74,45 @@ probable, decision-relevant, or causally related to an outcome.

The parser is deliberately not a semantic issue extractor. It performs no
sentiment analysis, inference, scoring, calibration, ranking, utility arithmetic,
causal estimation, or queue routing. Semantic assertions remain behind a separate
provider-neutral, human-validated boundary. Custom parser output is bounded,
causal estimation, or queue routing. Custom parser output is bounded,
canonicalized, and rebound to the exact verified source revision and span bytes
before it can cross the public API. Arbitrary provider exceptions are redacted.
Explicit-value caller metadata is restricted to the declared offset unit.

## Semantic issue extraction boundary

`extract_enterprise_atomic_issues()` is the provider-neutral trust boundary for
semantic issue proposals. It accepts exact source records, transient source text,
and an `EnterpriseAtomicIssueExtractor`, then returns only fresh canonical
`AtomicIssueRecord` values. The package imports no provider SDK and provides no
default production semantic model.

Before a provider runs, the boundary consumes source records with a fixed cap,
reconstructs exact source contracts, rejects duplicate source identities, requires
an exact source-text dictionary, and replays every Python character count and
SHA-256 fingerprint over valid UTF-8. Providers receive deterministic source
record order and a read-only transient text mapping. Every provider exception,
including package-domain exceptions, is replaced with a fixed redacted boundary
error.

Provider output must be an exact bounded tuple of exact `AtomicIssueRecord`
values. Each issue, evidence span, and counterevidence record is reconstructed as
a fresh canonical instance. Every source ID and source-record fingerprint must
name the same verified packet revision, and every span must replay its exact
code-point offsets and SHA-256 fingerprint over the corresponding UTF-8 slice.
Nested subclasses, malformed or mutated records, overlapping spans, duplicate
issues, duplicate logical issue IDs, and duplicate family/content revisions fail
closed. Returned issues use deterministic content order and retain no raw text.

`StaticEnterpriseIssueExtractor` is an offline fixture and integration adapter. It
returns only caller-declared issue records and performs no NLP, sentiment
analysis, inference, generation, ranking, or automatic issue discovery. Adding
sentiment-only text cannot create an issue in this path. Acceptance proves only
that a provider proposed one replayable canonical structure, not that the issue
is true, complete, material, probable, fair, construct-valid, or operationally
useful. Human validation and held-out provider evaluation remain prerequisites
for product claims.

## Replay and provenance

An `AtomicIssueRecord` binds one issue-content revision to declared source-record
Expand Down Expand Up @@ -116,7 +150,7 @@ and auditability but is not itself evidence that a claim is accurate or strong.

Stakeholder perspectives and candidate interventions must name the exact issue
content revision. Perspective evidence must also reference a source revision
already declared by the issue. Caller metadata cannot overwrite the managed
already declared by the issue. Caller metadata cannot overwrite managed
enterprise provenance fields.

This compiler performs deterministic validation and marshaling only. Existing
Expand All @@ -137,7 +171,7 @@ the issue declares counterevidence, the observation must also retain at least on
counterevidence reference rather than silently omitting contradictory evidence.
An engine that cannot satisfy those conditions must abstain with a stable reason
code. Abstention may retain no evidence and is not converted into a low score.
Caller confidence metadata cannot overwrite the managed enterprise provenance.
Caller confidence metadata cannot overwrite managed enterprise provenance.

The adapter does not calculate a rating or confidence value. Score categories,
criterion coverage, terminal-state semantics, engine identity, assessment and
Expand All @@ -149,8 +183,8 @@ is accurate, reliable, fair, valid, calibrated, or decision-ready.

These contracts improve traceability and replay resistance; they do not establish
construct validity, evidence truth, causal identification, model fairness, or
high-stakes deployment readiness. The request and observation compilers perform
no sentiment analysis, latent measurement, calibration, comparative ranking,
high-stakes deployment readiness. The extraction, request, and observation
adapters perform no latent measurement, calibration, comparative ranking,
expected utility, value-of-information, intervention-effect, or queue-routing
arithmetic.

Expand All @@ -164,9 +198,9 @@ legal rights, or material consequences are in dispute. A candidate intervention
is a caller-supplied hypothesis, not evidence of an identified causal effect.

ISO/IEC 42001:2023 remains published as Edition 1. ISO 8601-1:2019 and ISO
4217:2015 are the published standards used to describe the accepted date and
4217:2015 are the published standards used to describe accepted date and
currency-code forms; later amendments, maintenance updates, or replacement
editions must be evaluated before changing the parser grammar or allowlists. NIST
editions must be evaluated before changing parser grammar or allowlists. NIST
reports that AI RMF 1.0 is under revision as of August 2026, so this module cites
the current published framework without assuming that its terminology or
profiles are frozen.
Expand Down Expand Up @@ -195,7 +229,7 @@ risk management framework (AI RMF 1.0)* (NIST AI 100-1).
https://doi.org/10.6028/NIST.AI.100-1

Python Software Foundation. (2025). *Python 3.13 standard library: `datetime`,
`decimal`, `hashlib`, `re`, and `typing`*. https://docs.python.org/3.13/
`hashlib`, `types`, and `typing`*. https://docs.python.org/3.13/

The Unicode Consortium. (2025). *Unicode text segmentation* (Unicode Standard
Annex No. 29, Revision 47). https://www.unicode.org/reports/tr29/
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Enterprise semantic-issue provider boundary

## Objective

Advance issue #404 with the smallest provider-neutral semantic extraction slice
that can be reviewed independently after the deterministic explicit-value parser
and governed criterion-observation adapter. The slice lets offline fixtures,
human analysts, and future external engines propose the existing
`AtomicIssueRecord` contract without introducing a second issue, evidence,
observation, scoring, or engine schema.

## Architectural boundary

The implementation belongs under `fast_mlsirm.scoring.enterprise_issue` and
reuses:

- `EnterpriseSourceRecord` as the exact source-revision contract;
- `EvidenceSpanRecord` and `EnterpriseAssertionKind` for every semantic assertion;
- `CounterevidenceRecord` for counterevidence separation;
- `AtomicIssueRecord` as the only accepted semantic issue output; and
- the shared scoring request, observation, result, and engine contracts for later
criterion-level scoring.

The package must not import a provider SDK. Python may validate, replay,
canonicalize, redact, and marshal this boundary. This slice adds no likelihood,
gradient, Hessian, optimization, scoring, ranking, or utility arithmetic.

## Public API

Implement:

- runtime-checkable `EnterpriseAtomicIssueExtractor`;
- `extract_enterprise_atomic_issues()` as the fail-closed public entry point;
- bounded `MAX_ENTERPRISE_ATOMIC_ISSUES`; and
- `StaticEnterpriseIssueExtractor` as an offline fixture and integration adapter,
not a semantic language model or production default.

No competing extraction-request or semantic-assertion record is permitted where
the existing source, span, counterevidence, and atomic-issue contracts suffice.

## Trust-boundary requirements

The public entry point must:

1. consume source records through bounded iteration;
2. require exact `EnterpriseSourceRecord` values, unique source IDs, unique source
record fingerprints, one schema version, and deterministic ordering;
3. require an exact dictionary whose keys equal the declared source IDs;
4. replay transient source text against its Python character count, UTF-8
encodability, and SHA-256 content fingerprint;
5. invoke only an object satisfying the provider-neutral protocol;
6. redact every provider exception, including structured domain exceptions;
7. accept only a bounded exact tuple of exact `AtomicIssueRecord` values;
8. reconstruct fresh canonical issue, evidence-span, and counterevidence objects;
9. bind every referenced source fingerprint and source ID to the same supplied
source revision;
10. verify every code-point span offset and SHA-256 fingerprint over the exact
UTF-8 slice;
11. preserve all five assertion kinds and wrapped counterevidence;
12. reject duplicate issue fingerprints, duplicate issue IDs, duplicate
family/revision pairs, overlapping or duplicated nested spans, malformed
nested records, and oversized outputs;
13. return deterministic content order; and
14. retain no raw source text or clear-text semantic issue text in public records,
exceptions, metadata, logs, or serialized output.

Use stable structured error codes and JSON paths. Never reflect untrusted values
in error messages.

## Scientific and product limits

An accepted record proves only that an extractor proposed one canonical
issue/evidence structure whose spans replay against exact source revisions. It
does not prove that the issue is true, complete, material, probable, causally
related to an outcome, fair, construct-valid, or suitable for intervention
automation. An inference is not converted into a fact, and counterevidence is not
assumed weaker than supporting evidence.

The fixture extractor must not be described as a semantic model. Human validation
and held-out provider evaluation remain prerequisites for product claims.

## Validation

Tests must provide complete statement and branch coverage and demonstrate:

- deterministic output under source-record and issue reordering;
- exact source replay, Unicode code-point offsets, and UTF-8 span fingerprints;
- survival of all five assertion kinds without epistemic collapse;
- fresh canonical reconstruction and rejection of mutated or subclassed nested
records;
- provider exception redaction and privacy preservation;
- missing, extra, duplicated, mismatched, oversized, or unexpectedly prolific
source/output collections failing before unbounded consumption;
- source ID/fingerprint pair consistency;
- changed text, offsets, or span bytes invalidating replay;
- duplicate and overlapping nested evidence rejection;
- sentiment-only source text creating no issue in the deterministic fixture path;
and
- stable package exports and serialized shapes.

Run Ruff, focused and repository tests, branch coverage, changelog parity,
packaging, Security Scan, SAST, and exact-head acceptance gates. Every public
object requires a complete docstring.

## Documentation and changelog

Update `docs/enterprise_issue_evidence_contracts.md` with provider trust,
source/span replay, fixture limitations, exception redaction, and conservative
interpretation limits. Add an authoritative changelog fragment and render
`CHANGELOG.md`. Do not bump a version or publish a release for this isolated
issue #404 slice.

## Review discipline

Keep the pull request draft until its exact current head has no unresolved valid
human, CodeRabbit, security, Dependabot, or automated feedback and all required
gates pass. Do not leave temporary workflows, triggers, credentials, raw source
fixtures, or generated artifacts in the final tree.
24 changes: 18 additions & 6 deletions python/fast_mlsirm/scoring/enterprise_issue/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@
from .contracts import MAX_ENTERPRISE_STAKEHOLDERS as MAX_ENTERPRISE_STAKEHOLDERS
from .contracts import StakeholderPerspective as StakeholderPerspective
from .explicit_values import DEFAULT_CURRENCY_CODES as DEFAULT_CURRENCY_CODES
from .explicit_values import (
MAX_CURRENCY_CODES as MAX_CURRENCY_CODES,
)
from .explicit_values import MAX_CURRENCY_CODES as MAX_CURRENCY_CODES
from .explicit_values import (
MAX_CUSTOMER_IDENTIFIER_CHARACTERS as MAX_CUSTOMER_IDENTIFIER_CHARACTERS,
)
from .explicit_values import (
MAX_EXPLICIT_VALUE_RECORDS as MAX_EXPLICIT_VALUE_RECORDS,
)
from .explicit_values import MAX_EXPLICIT_VALUE_RECORDS as MAX_EXPLICIT_VALUE_RECORDS
from .explicit_values import (
DeterministicExplicitValueParser as DeterministicExplicitValueParser,
)
Expand All @@ -45,11 +41,24 @@
from .request import (
enterprise_issue_evidence_references as enterprise_issue_evidence_references,
)
from .semantic import (
MAX_ENTERPRISE_ATOMIC_ISSUES as MAX_ENTERPRISE_ATOMIC_ISSUES,
)
from .semantic import (
EnterpriseAtomicIssueExtractor as EnterpriseAtomicIssueExtractor,
)
from .semantic import (
StaticEnterpriseIssueExtractor as StaticEnterpriseIssueExtractor,
)
from .semantic import (
extract_enterprise_atomic_issues as extract_enterprise_atomic_issues,
)

__all__ = [
"DEFAULT_CURRENCY_CODES",
"MAX_CURRENCY_CODES",
"MAX_CUSTOMER_IDENTIFIER_CHARACTERS",
"MAX_ENTERPRISE_ATOMIC_ISSUES",
"MAX_ENTERPRISE_ISSUE_EVIDENCE",
"MAX_ENTERPRISE_ISSUE_SOURCES",
"MAX_ENTERPRISE_SOURCE_CHARACTERS",
Expand All @@ -60,14 +69,17 @@
"CounterevidenceRecord",
"DeterministicExplicitValueParser",
"EnterpriseAssertionKind",
"EnterpriseAtomicIssueExtractor",
"EnterpriseExplicitValueParser",
"EnterpriseSourceRecord",
"EvidenceSpanRecord",
"ExplicitValueKind",
"ExplicitValueRecord",
"StakeholderPerspective",
"StaticEnterpriseIssueExtractor",
"build_enterprise_issue_score_observation",
"build_enterprise_issue_scoring_request",
"enterprise_issue_evidence_references",
"extract_enterprise_atomic_issues",
"parse_enterprise_explicit_values",
]
Loading
Loading