payer-agent-audit 0.1.4__py3-none-any.whl

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.
@@ -0,0 +1,63 @@
1
+ """Governance patterns for autonomous AI agents in health-insurance / payer
2
+ operations (NAIC umbrella).
3
+
4
+ These are reference IP for adoption — documented, tested patterns — NOT a
5
+ deployed control operating in production. The deployer's substrate is the
6
+ production deployment. See LIMITATIONS.md and DISCLAIMER.md.
7
+
8
+ This library makes NO medical-necessity or clinical determination. A payer
9
+ coverage decision is a benefit adjudication under insurance law (NAIC /
10
+ state DOI / ERISA 29 CFR 2560.503-1 / CMS / ACA 45 CFR 147.136), distinct
11
+ from FDA Software-as-a-Medical-Device regulation. See the payer-not-FDA-SaMD
12
+ boundary in LIMITATIONS.md.
13
+
14
+ The headline primitives and controls are re-exported here for convenience::
15
+
16
+ from payer_agent_audit import AuditChain, SovereignVeto, DEFCONMachine
17
+ from payer_agent_audit import UMTimelinessControl, FundingType
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from payer_agent_audit.governance import (
23
+ DEFCON,
24
+ AuditChain,
25
+ DEFCONMachine,
26
+ EffectiveChallengeHarness,
27
+ SovereignVeto,
28
+ check_a2_to_a3_promotion,
29
+ )
30
+ from payer_agent_audit.payer import (
31
+ AppealIROControl,
32
+ ClinicianOfRecordControl,
33
+ FundingType,
34
+ RequestCategory,
35
+ UMTimelinessControl,
36
+ obligations_for,
37
+ )
38
+ from payer_agent_audit.schemas import (
39
+ AuditEvent,
40
+ AuditEventType,
41
+ AutonomyLevel,
42
+ )
43
+
44
+ __version__ = "0.1.4"
45
+
46
+ __all__ = [
47
+ "AppealIROControl",
48
+ "AuditChain",
49
+ "AuditEvent",
50
+ "AuditEventType",
51
+ "AutonomyLevel",
52
+ "ClinicianOfRecordControl",
53
+ "DEFCON",
54
+ "DEFCONMachine",
55
+ "EffectiveChallengeHarness",
56
+ "FundingType",
57
+ "RequestCategory",
58
+ "SovereignVeto",
59
+ "UMTimelinessControl",
60
+ "__version__",
61
+ "check_a2_to_a3_promotion",
62
+ "obligations_for",
63
+ ]
@@ -0,0 +1,41 @@
1
+ """Shared identity normalization for governance guards.
2
+
3
+ The self-attestation (P1), self-clear (P2), effective-challenge (P5), and
4
+ ERISA full-and-fair-review independence (appeal/IRO) guards all compare
5
+ caller-supplied principal identifiers. A naive ``==`` (or even
6
+ ``.strip().casefold()``) is defeated by Unicode confusables and zero-width
7
+ characters — e.g. a fullwidth ``agent`` (U+FF41) or a zero-width-space
8
+ injection reads as a *different* string and slips past the guard, letting an
9
+ agent self-attest or self-clear. ``normalize_principal_id`` closes that class
10
+ by applying NFKC compatibility folding, stripping the zero-width set, and
11
+ casefolding, so equivalent identifiers compare equal.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import unicodedata
17
+
18
+ # Zero-width and BOM characters that ``str.strip()`` does NOT remove but that
19
+ # must not be allowed to disguise one principal as another.
20
+ _ZERO_WIDTH = dict.fromkeys(
21
+ [
22
+ 0x200B, # ZERO WIDTH SPACE
23
+ 0x200C, # ZERO WIDTH NON-JOINER
24
+ 0x200D, # ZERO WIDTH JOINER
25
+ 0x2060, # WORD JOINER
26
+ 0xFEFF, # ZERO WIDTH NO-BREAK SPACE / BOM
27
+ ]
28
+ )
29
+
30
+
31
+ def normalize_principal_id(value: str) -> str:
32
+ """Return a canonical form of a principal identifier for guard comparison.
33
+
34
+ NFKC compatibility-folds confusables (fullwidth/compatibility forms),
35
+ removes zero-width characters, strips surrounding whitespace, and
36
+ casefolds. Two identifiers that a human would read as the same principal
37
+ normalize to the same string; a blank-after-normalization id returns "".
38
+ """
39
+ folded = unicodedata.normalize("NFKC", value)
40
+ folded = folded.translate(_ZERO_WIDTH)
41
+ return folded.strip().casefold()
@@ -0,0 +1 @@
1
+ """Reference agents (documented patterns, not deployed controls)."""
@@ -0,0 +1,117 @@
1
+ """payer-audit CLI — verify an audit chain + show obligation routing.
2
+
3
+ Deployer-facing entry point (``payer-audit``). Stdlib-only. Subcommands:
4
+
5
+ verify --jsonl <path> verify a JSONL audit chain
6
+ info print version + the five primitives
7
+ obligations --funding <t> --category <c>
8
+ print the obligation routing for a
9
+ (funding_type, request category)
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import argparse
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ from payer_agent_audit import __version__
19
+ from payer_agent_audit.governance.audit_chain import AuditChain, AuditChainTamperError
20
+ from payer_agent_audit.payer.funding_type import (
21
+ FundingType,
22
+ RequestCategory,
23
+ obligations_for,
24
+ )
25
+
26
+ _PRIMITIVES = [
27
+ "P1 AutonomyLadder level-gate (independent attestation, advisory-labeled)",
28
+ "P2 SovereignVeto (mandatory authorizer in production, un-self-clearable)",
29
+ "P3 AuditChain (genesis-branching verifier, witness anchor in production)",
30
+ "P4 DEFCONMachine (transition-direction guard)",
31
+ "P5 EffectiveChallengeHarness (challenger != primary, attested independence)",
32
+ ]
33
+
34
+
35
+ def _cmd_info(_: argparse.Namespace) -> int:
36
+ print(f"payer-agent-audit {__version__}")
37
+ print("aligned to the NAIC Model Bulletin framework · module (a) health-payer")
38
+ print("Five corrected-spec primitives:")
39
+ for p in _PRIMITIVES:
40
+ print(f" - {p}")
41
+ print(
42
+ "\nReference IP for adoption — NOT a deployed control. Makes no "
43
+ "medical-necessity / clinical determination. See LIMITATIONS.md."
44
+ )
45
+ return 0
46
+
47
+
48
+ def _cmd_verify(args: argparse.Namespace) -> int:
49
+ path = Path(args.jsonl)
50
+ if not path.exists():
51
+ print(f"error: {path} not found", file=sys.stderr)
52
+ return 2
53
+ try:
54
+ chain = AuditChain(log_file=path)
55
+ chain.verify_strict()
56
+ except AuditChainTamperError as exc:
57
+ print(f"TAMPER DETECTED: {exc}", file=sys.stderr)
58
+ return 1
59
+ print(f"OK: chain verified ({len(chain)} events), head={chain.chain_head()[:16]}...")
60
+ return 0
61
+
62
+
63
+ def _cmd_obligations(args: argparse.Namespace) -> int:
64
+ # argparse `choices=` (build_parser) already restricts --funding/--category
65
+ # to valid enum values, so these conversions cannot raise here.
66
+ funding = FundingType(args.funding)
67
+ category = RequestCategory(args.category)
68
+ ob = obligations_for(funding, category)
69
+ print(f"funding_type : {ob.funding_type.value}")
70
+ print(f"category : {ob.category.value}")
71
+ print(f"primary_regulator : {ob.primary_regulator}")
72
+ dl = ob.timeliness.deadline
73
+ print(f"timeliness_deadline : {dl if dl is not None else 'deployer-supplied (state-specific)'}")
74
+ print(f"timeliness_verified : {ob.timeliness.verified}")
75
+ print(f"citation : {ob.timeliness.citation}")
76
+ print(f"appeal_regime : {ob.appeal_regime}")
77
+ print(f"external_review : {ob.external_review_citation}")
78
+ return 0
79
+
80
+
81
+ def build_parser() -> argparse.ArgumentParser:
82
+ parser = argparse.ArgumentParser(prog="payer-audit", description=__doc__)
83
+ sub = parser.add_subparsers(dest="command", required=True)
84
+
85
+ p_info = sub.add_parser("info", help="print version + the five primitives")
86
+ p_info.set_defaults(func=_cmd_info)
87
+
88
+ p_verify = sub.add_parser("verify", help="verify a JSONL audit chain")
89
+ p_verify.add_argument("--jsonl", required=True, help="path to the JSONL chain")
90
+ p_verify.set_defaults(func=_cmd_verify)
91
+
92
+ p_ob = sub.add_parser("obligations", help="print obligation routing")
93
+ p_ob.add_argument(
94
+ "--funding",
95
+ required=True,
96
+ choices=[f.value for f in FundingType],
97
+ help="funding type",
98
+ )
99
+ p_ob.add_argument(
100
+ "--category",
101
+ required=True,
102
+ choices=[c.value for c in RequestCategory],
103
+ help="request category",
104
+ )
105
+ p_ob.set_defaults(func=_cmd_obligations)
106
+ return parser
107
+
108
+
109
+ def main(argv: list[str] | None = None) -> int:
110
+ parser = build_parser()
111
+ args = parser.parse_args(argv)
112
+ result: int = args.func(args)
113
+ return result
114
+
115
+
116
+ if __name__ == "__main__":
117
+ raise SystemExit(main())
@@ -0,0 +1,82 @@
1
+ """Governance primitives for payer-agent-audit.
2
+
3
+ The five corrected-spec primitives:
4
+ P1 AutonomyLadder level-gate (autonomy_ladder.py)
5
+ P2 SovereignVeto (sovereign_veto.py)
6
+ P3 AuditChain (audit_chain.py)
7
+ P4 DEFCONMachine (defcon.py)
8
+ P5 EffectiveChallengeHarness (effective_challenge_harness.py)
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from payer_agent_audit.governance.audit_chain import AuditChain, AuditChainTamperError
14
+ from payer_agent_audit.governance.autonomy_ladder import (
15
+ ADVISORY,
16
+ Attestation,
17
+ PromotionEvidence,
18
+ PromotionGateNotMet,
19
+ PromotionGateReport,
20
+ check_a2_to_a3_promotion,
21
+ required_oversight,
22
+ )
23
+ from payer_agent_audit.governance.defcon import (
24
+ DEFCON,
25
+ DEFCONMachine,
26
+ DEFCONOverrideRejectedError,
27
+ RiskMetrics,
28
+ )
29
+ from payer_agent_audit.governance.effective_challenge_harness import (
30
+ ChallengeReport,
31
+ ChallengerNotIndependentError,
32
+ EffectiveChallengeHarness,
33
+ IndependenceAttestation,
34
+ )
35
+ from payer_agent_audit.governance.sovereign_veto import (
36
+ Authorizer,
37
+ InMemoryVetoStateStore,
38
+ SovereignVeto,
39
+ VetoBlockedError,
40
+ VetoReason,
41
+ VetoRecord,
42
+ VetoStateStore,
43
+ )
44
+ from payer_agent_audit.governance.witness_anchor import (
45
+ InMemoryWitness,
46
+ RekorWitness,
47
+ WitnessReceipt,
48
+ WitnessRegister,
49
+ anchor_to_witness,
50
+ )
51
+
52
+ __all__ = [
53
+ "ADVISORY",
54
+ "Attestation",
55
+ "AuditChain",
56
+ "AuditChainTamperError",
57
+ "Authorizer",
58
+ "ChallengeReport",
59
+ "ChallengerNotIndependentError",
60
+ "DEFCON",
61
+ "DEFCONMachine",
62
+ "DEFCONOverrideRejectedError",
63
+ "EffectiveChallengeHarness",
64
+ "InMemoryVetoStateStore",
65
+ "InMemoryWitness",
66
+ "IndependenceAttestation",
67
+ "PromotionEvidence",
68
+ "PromotionGateNotMet",
69
+ "PromotionGateReport",
70
+ "RekorWitness",
71
+ "RiskMetrics",
72
+ "SovereignVeto",
73
+ "VetoBlockedError",
74
+ "VetoReason",
75
+ "VetoRecord",
76
+ "VetoStateStore",
77
+ "WitnessReceipt",
78
+ "WitnessRegister",
79
+ "anchor_to_witness",
80
+ "check_a2_to_a3_promotion",
81
+ "required_oversight",
82
+ ]