truth-firewall 0.1.0__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.
Files changed (80) hide show
  1. truth_firewall/__init__.py +7 -0
  2. truth_firewall/__main__.py +4 -0
  3. truth_firewall/audit.py +30 -0
  4. truth_firewall/claims/__init__.py +6 -0
  5. truth_firewall/claims/coverage.py +40 -0
  6. truth_firewall/claims/deterministic.py +822 -0
  7. truth_firewall/claims/extractor.py +22 -0
  8. truth_firewall/claims/normalization.py +426 -0
  9. truth_firewall/claims/prompts.py +47 -0
  10. truth_firewall/claims/proposition.py +324 -0
  11. truth_firewall/claims/semantic.py +76 -0
  12. truth_firewall/cli.py +204 -0
  13. truth_firewall/codex_worker.py +75 -0
  14. truth_firewall/completion.py +229 -0
  15. truth_firewall/constants.py +40 -0
  16. truth_firewall/contract_coverage.py +278 -0
  17. truth_firewall/coverage_authority.py +379 -0
  18. truth_firewall/demo.py +107 -0
  19. truth_firewall/errors.py +29 -0
  20. truth_firewall/evidence/__init__.py +5 -0
  21. truth_firewall/evidence/collectors/__init__.py +15 -0
  22. truth_firewall/evidence/collectors/filesystem.py +218 -0
  23. truth_firewall/evidence/collectors/git.py +98 -0
  24. truth_firewall/evidence/collectors/process.py +117 -0
  25. truth_firewall/evidence/collectors/runtime.py +42 -0
  26. truth_firewall/evidence/collectors/structure.py +131 -0
  27. truth_firewall/evidence/collectors/test_runner.py +610 -0
  28. truth_firewall/evidence/executable_identity.py +168 -0
  29. truth_firewall/evidence/execution_environment.py +82 -0
  30. truth_firewall/evidence/git_identity.py +80 -0
  31. truth_firewall/evidence/io.py +123 -0
  32. truth_firewall/evidence/ledger.py +66 -0
  33. truth_firewall/evidence/local.py +47 -0
  34. truth_firewall/evidence/provenance.py +264 -0
  35. truth_firewall/evidence/pytest_result.py +112 -0
  36. truth_firewall/evidence/retriever.py +113 -0
  37. truth_firewall/evidence_requirements.py +63 -0
  38. truth_firewall/fixtures/demo/contradicted.json +30 -0
  39. truth_firewall/fixtures/demo/legitimate_hypothesis.json +20 -0
  40. truth_firewall/fixtures/demo/mixed.json +38 -0
  41. truth_firewall/fixtures/demo/overclaimed_completion.json +40 -0
  42. truth_firewall/fixtures/demo/scoped_absence.json +37 -0
  43. truth_firewall/fixtures/demo/supported_factual.json +28 -0
  44. truth_firewall/fixtures/demo/unsupported_causal.json +33 -0
  45. truth_firewall/generic_completion.py +467 -0
  46. truth_firewall/integrations/__init__.py +5 -0
  47. truth_firewall/integrations/codex.py +371 -0
  48. truth_firewall/integrations/cursor.py +366 -0
  49. truth_firewall/integrations/local_test_results.py +117 -0
  50. truth_firewall/lifecycle.py +298 -0
  51. truth_firewall/onboarding.py +133 -0
  52. truth_firewall/pilot.py +261 -0
  53. truth_firewall/pipeline.py +432 -0
  54. truth_firewall/policy/__init__.py +5 -0
  55. truth_firewall/policy/engine.py +41 -0
  56. truth_firewall/providers/__init__.py +6 -0
  57. truth_firewall/providers/base.py +18 -0
  58. truth_firewall/providers/config.py +40 -0
  59. truth_firewall/providers/fake.py +52 -0
  60. truth_firewall/providers/openai_compatible.py +133 -0
  61. truth_firewall/py.typed +0 -0
  62. truth_firewall/redaction.py +36 -0
  63. truth_firewall/rewrite/__init__.py +5 -0
  64. truth_firewall/rewrite/rewriter.py +151 -0
  65. truth_firewall/safety.py +69 -0
  66. truth_firewall/schemas.py +606 -0
  67. truth_firewall/storage.py +139 -0
  68. truth_firewall/supervised_worker.py +333 -0
  69. truth_firewall/verification/__init__.py +5 -0
  70. truth_firewall/verification/contracts.py +40 -0
  71. truth_firewall/verification/entailment.py +357 -0
  72. truth_firewall/verification/rules.py +971 -0
  73. truth_firewall/verification/verifier.py +99 -0
  74. truth_firewall/workspace.py +90 -0
  75. truth_firewall-0.1.0.dist-info/METADATA +141 -0
  76. truth_firewall-0.1.0.dist-info/RECORD +80 -0
  77. truth_firewall-0.1.0.dist-info/WHEEL +5 -0
  78. truth_firewall-0.1.0.dist-info/entry_points.txt +2 -0
  79. truth_firewall-0.1.0.dist-info/licenses/LICENSE +21 -0
  80. truth_firewall-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,7 @@
1
+ """Truth Firewall: unsupported claims are not presented as verified."""
2
+
3
+ __version__ = "0.1.0"
4
+
5
+ from truth_firewall.pipeline import CheckResult, check_response
6
+
7
+ __all__ = ["CheckResult", "check_response", "__version__"]
@@ -0,0 +1,4 @@
1
+ from truth_firewall.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ raise SystemExit(main())
@@ -0,0 +1,30 @@
1
+ """Local audit artifacts for one check, with contained exclusive run storage."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ from truth_firewall.storage import ensure_directory, ensure_root, write_text
10
+
11
+
12
+ def write_audit(directory: Path, artifacts: dict[str, Any], *, permitted_root: Path | None = None) -> None:
13
+ configured = permitted_root if permitted_root is not None else directory.parent
14
+ relative = directory.relative_to(configured)
15
+ root = ensure_root(configured)
16
+ directory = ensure_directory(root, root / relative, exclusive=True)
17
+ mapping = {
18
+ "meta.json": artifacts.get("meta", {}),
19
+ "claims.json": artifacts.get("claims", []),
20
+ "evidence.json": artifacts.get("evidence", []),
21
+ "candidates.json": artifacts.get("candidates", {}),
22
+ "assessments.json": artifacts.get("assessments", []),
23
+ "decisions.json": artifacts.get("decisions", []),
24
+ "coverage.json": artifacts.get("coverage", []),
25
+ "errors.json": artifacts.get("errors", []),
26
+ }
27
+ for name, payload in mapping.items():
28
+ write_text(root, directory / name, json.dumps(payload, indent=2, ensure_ascii=False, default=str))
29
+ write_text(root, directory / "response.txt", str(artifacts.get("response", "")))
30
+ write_text(root, directory / "grounded.txt", str(artifacts.get("grounded", "")))
@@ -0,0 +1,6 @@
1
+ """Claim extraction."""
2
+
3
+ from truth_firewall.claims.deterministic import DeterministicFallbackExtractor
4
+ from truth_firewall.claims.semantic import SemanticClaimExtractor
5
+
6
+ __all__ = ["DeterministicFallbackExtractor", "SemanticClaimExtractor"]
@@ -0,0 +1,40 @@
1
+ """Find assertive residual source text that no extracted claim covers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+
7
+ from truth_firewall.claims.deterministic import may_contain_unextracted_fact
8
+ from truth_firewall.schemas import Claim
9
+
10
+ _CONNECTOR_ONLY = re.compile(r"[\W_]*(?:(?:and|but|or|while|although|because|therefore|then|also)[\W_]*)*", re.I)
11
+
12
+
13
+ def uncovered_assertive_spans(response_text: str, claims: list[Claim]) -> list[tuple[int, int]]:
14
+ """A partial extraction must not disable the zero-claim safety principle."""
15
+ covered: list[tuple[int, int]] = []
16
+ for claim in claims:
17
+ start, end = claim.source_start, claim.source_end
18
+ if (start is None or end is None or start < 0 or end > len(response_text)
19
+ or response_text[start:end] != claim.raw_text):
20
+ continue
21
+ covered.append((start, end))
22
+ if not covered:
23
+ return [] # The pipeline's existing zero-claim guard handles this case.
24
+ covered.sort()
25
+ merged = [covered[0]]
26
+ for start, end in covered[1:]:
27
+ left, right = merged[-1]
28
+ if start <= right:
29
+ merged[-1] = (left, max(right, end))
30
+ else:
31
+ merged.append((start, end))
32
+ gaps: list[tuple[int, int]] = []
33
+ cursor = 0
34
+ for start, end in [*merged, (len(response_text), len(response_text))]:
35
+ if cursor < start:
36
+ gap = response_text[cursor:start]
37
+ if _CONNECTOR_ONLY.fullmatch(gap) is None and may_contain_unextracted_fact(gap):
38
+ gaps.append((cursor, start))
39
+ cursor = end
40
+ return gaps