alignmenter 0.2.0__tar.gz → 0.3.0__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.
Files changed (154) hide show
  1. alignmenter-0.3.0/MANIFEST.in +8 -0
  2. alignmenter-0.3.0/PKG-INFO +553 -0
  3. {alignmenter-0.2.0 → alignmenter-0.3.0}/README.md +80 -92
  4. alignmenter-0.3.0/configs/run-grounded.yaml +36 -0
  5. alignmenter-0.3.0/datasets/README.md +615 -0
  6. alignmenter-0.3.0/datasets/grounded_demo.jsonl +6 -0
  7. alignmenter-0.3.0/datasets/wendys_twitter.jsonl +235 -0
  8. {alignmenter-0.2.0 → alignmenter-0.3.0}/pyproject.toml +13 -7
  9. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/__init__.py +2 -2
  10. alignmenter-0.3.0/src/alignmenter/_version.py +3 -0
  11. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/cli.py +300 -7
  12. alignmenter-0.3.0/src/alignmenter/data/configs/demo_config.yaml +15 -0
  13. alignmenter-0.3.0/src/alignmenter/data/configs/judges/safety_prompt.txt +2 -0
  14. alignmenter-0.3.0/src/alignmenter/data/configs/persona/default.yaml +64 -0
  15. alignmenter-0.3.0/src/alignmenter/data/configs/run-grounded.yaml +36 -0
  16. alignmenter-0.3.0/src/alignmenter/data/configs/run.yaml +12 -0
  17. alignmenter-0.3.0/src/alignmenter/data/configs/safety_keywords.yaml +7 -0
  18. alignmenter-0.3.0/src/alignmenter/data/datasets/demo_conversations.jsonl +60 -0
  19. alignmenter-0.3.0/src/alignmenter/data/datasets/grounded_demo.jsonl +6 -0
  20. alignmenter-0.3.0/src/alignmenter/evaluators/__init__.py +1 -0
  21. alignmenter-0.3.0/src/alignmenter/evaluators/custom.py +68 -0
  22. alignmenter-0.3.0/src/alignmenter/evaluators/evidence.py +37 -0
  23. alignmenter-0.3.0/src/alignmenter/evaluators/faithfulness.py +35 -0
  24. alignmenter-0.3.0/src/alignmenter/evaluators/grounding.py +119 -0
  25. alignmenter-0.3.0/src/alignmenter/evaluators/metrics.py +76 -0
  26. alignmenter-0.3.0/src/alignmenter/examples/__init__.py +1 -0
  27. alignmenter-0.3.0/src/alignmenter/examples/resource_task.py +58 -0
  28. alignmenter-0.3.0/src/alignmenter/execution/__init__.py +1 -0
  29. alignmenter-0.3.0/src/alignmenter/execution/archive.py +111 -0
  30. alignmenter-0.3.0/src/alignmenter/execution/artifacts.py +26 -0
  31. alignmenter-0.3.0/src/alignmenter/execution/comparison.py +140 -0
  32. alignmenter-0.3.0/src/alignmenter/execution/evaluation.py +358 -0
  33. alignmenter-0.3.0/src/alignmenter/execution/gates.py +71 -0
  34. alignmenter-0.3.0/src/alignmenter/execution/leases.py +45 -0
  35. alignmenter-0.3.0/src/alignmenter/execution/legacy.py +151 -0
  36. alignmenter-0.3.0/src/alignmenter/execution/recovery.py +223 -0
  37. alignmenter-0.3.0/src/alignmenter/execution/review.py +139 -0
  38. alignmenter-0.3.0/src/alignmenter/execution/suite.py +118 -0
  39. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/judges/prompts.py +77 -0
  40. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/base.py +6 -2
  41. alignmenter-0.3.0/src/alignmenter/providers/callable.py +51 -0
  42. alignmenter-0.3.0/src/alignmenter/providers/durable_judge.py +73 -0
  43. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/judges.py +42 -0
  44. alignmenter-0.3.0/src/alignmenter/release_cli.py +169 -0
  45. alignmenter-0.3.0/src/alignmenter/reporting/durable.py +171 -0
  46. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/reporting/html.py +62 -0
  47. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/run_config.py +40 -1
  48. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/runner.py +184 -62
  49. alignmenter-0.3.0/src/alignmenter/schemas/__init__.py +1 -0
  50. alignmenter-0.3.0/src/alignmenter/schemas/evaluation.py +239 -0
  51. alignmenter-0.3.0/src/alignmenter/schemas/execution.py +214 -0
  52. alignmenter-0.3.0/src/alignmenter/schemas/gates.py +38 -0
  53. alignmenter-0.3.0/src/alignmenter/schemas/metrics.py +65 -0
  54. alignmenter-0.3.0/src/alignmenter/schemas/review.py +47 -0
  55. alignmenter-0.3.0/src/alignmenter/schemas/scoring.py +130 -0
  56. alignmenter-0.3.0/src/alignmenter/schemas/suite.py +41 -0
  57. alignmenter-0.3.0/src/alignmenter/scorers/__init__.py +48 -0
  58. alignmenter-0.3.0/src/alignmenter/scorers/faithfulness.py +278 -0
  59. alignmenter-0.3.0/src/alignmenter/scorers/grounding.py +267 -0
  60. alignmenter-0.3.0/src/alignmenter/sdk.py +53 -0
  61. alignmenter-0.3.0/src/alignmenter/storage/__init__.py +5 -0
  62. alignmenter-0.3.0/src/alignmenter/storage/evaluations.py +312 -0
  63. alignmenter-0.3.0/src/alignmenter/storage/reviews.py +53 -0
  64. alignmenter-0.3.0/src/alignmenter/storage/runs.py +473 -0
  65. alignmenter-0.3.0/src/alignmenter.egg-info/PKG-INFO +553 -0
  66. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/SOURCES.txt +72 -1
  67. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/requires.txt +13 -2
  68. alignmenter-0.3.0/tests/__init__.py +1 -0
  69. alignmenter-0.3.0/tests/conftest.py +11 -0
  70. alignmenter-0.3.0/tests/data/durable_evaluation_judge.py +51 -0
  71. alignmenter-0.3.0/tests/data/durable_evaluation_worker.py +32 -0
  72. alignmenter-0.3.0/tests/data/durable_recovery_target.py +51 -0
  73. alignmenter-0.3.0/tests/data/durable_recovery_worker.py +28 -0
  74. alignmenter-0.3.0/tests/data/durable_run_worker.py +66 -0
  75. alignmenter-0.3.0/tests/data/mini_cli_dataset.jsonl +4 -0
  76. alignmenter-0.3.0/tests/test_builtin_evaluations.py +324 -0
  77. alignmenter-0.3.0/tests/test_capture_recovery.py +380 -0
  78. alignmenter-0.3.0/tests/test_cli_grounded.py +91 -0
  79. alignmenter-0.3.0/tests/test_durable_evaluations.py +473 -0
  80. alignmenter-0.3.0/tests/test_durable_execution.py +443 -0
  81. alignmenter-0.3.0/tests/test_faithfulness.py +199 -0
  82. alignmenter-0.3.0/tests/test_grounding.py +112 -0
  83. alignmenter-0.3.0/tests/test_release_workflow.py +206 -0
  84. alignmenter-0.3.0/tests/test_review_workflow.py +152 -0
  85. alignmenter-0.3.0/tests/test_run_config_grounded.py +67 -0
  86. alignmenter-0.3.0/tests/test_suite_archive.py +181 -0
  87. alignmenter-0.2.0/PKG-INFO +0 -757
  88. alignmenter-0.2.0/src/alignmenter/scorers/__init__.py +0 -7
  89. alignmenter-0.2.0/src/alignmenter.egg-info/PKG-INFO +0 -757
  90. {alignmenter-0.2.0 → alignmenter-0.3.0}/LICENSE +0 -0
  91. {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/demo_config.yaml +0 -0
  92. {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/judges/safety_prompt.txt +0 -0
  93. {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/persona/default.yaml +0 -0
  94. {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/run.yaml +0 -0
  95. {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/safety_keywords.yaml +0 -0
  96. {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/datasets/demo_conversations.jsonl +0 -0
  97. {alignmenter-0.2.0 → alignmenter-0.3.0}/setup.cfg +0 -0
  98. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/__init__.py +0 -0
  99. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/analyze.py +0 -0
  100. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/bounds.py +0 -0
  101. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/diagnose.py +0 -0
  102. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/generate.py +0 -0
  103. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/label.py +0 -0
  104. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/optimize.py +0 -0
  105. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/sampling.py +0 -0
  106. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/validate.py +0 -0
  107. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/config.py +0 -0
  108. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/judges/__init__.py +0 -0
  109. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/judges/authenticity_judge.py +0 -0
  110. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/__init__.py +0 -0
  111. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/anthropic.py +0 -0
  112. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/classifiers.py +0 -0
  113. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/embeddings.py +0 -0
  114. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/local.py +0 -0
  115. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/openai.py +0 -0
  116. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/reporting/__init__.py +0 -0
  117. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/reporting/json_out.py +0 -0
  118. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scorers/authenticity.py +0 -0
  119. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scorers/safety.py +0 -0
  120. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scorers/stability.py +0 -0
  121. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/__init__.py +0 -0
  122. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/bootstrap_dataset.py +0 -0
  123. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/calibrate_persona.py +0 -0
  124. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/run_openai_demo.py +0 -0
  125. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/sanitize_dataset.py +0 -0
  126. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/__init__.py +0 -0
  127. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/io.py +0 -0
  128. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/optional.py +0 -0
  129. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/tokens.py +0 -0
  130. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/yaml.py +0 -0
  131. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/dependency_links.txt +0 -0
  132. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/entry_points.txt +0 -0
  133. {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/top_level.txt +0 -0
  134. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_authenticity_judge.py +0 -0
  135. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_calibrate_persona.py +0 -0
  136. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_errors.py +0 -0
  137. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_helpers.py +0 -0
  138. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_import.py +0 -0
  139. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_init.py +0 -0
  140. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_run_config.py +0 -0
  141. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_config.py +0 -0
  142. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_html_report.py +0 -0
  143. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_judge_providers.py +0 -0
  144. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_offline_safety.py +0 -0
  145. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_persona_gpt.py +0 -0
  146. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_provider_local.py +0 -0
  147. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_provider_openai.py +0 -0
  148. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_providers.py +0 -0
  149. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_run_config_loader.py +0 -0
  150. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_run_openai_demo.py +0 -0
  151. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_runner.py +0 -0
  152. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_sampling.py +0 -0
  153. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_scorers.py +0 -0
  154. {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_smoke.py +0 -0
@@ -0,0 +1,8 @@
1
+ include LICENSE README.md
2
+ recursive-include tests *.py *.json *.jsonl *.yaml *.yml *.txt *.csv
3
+ recursive-include configs *.yaml *.yml *.json *.txt
4
+ recursive-include datasets *.jsonl *.md
5
+ recursive-include src/alignmenter/data *.yaml *.yml *.jsonl *.txt
6
+ prune build
7
+ prune dist
8
+ prune reports
@@ -0,0 +1,553 @@
1
+ Metadata-Version: 2.4
2
+ Name: alignmenter
3
+ Version: 0.3.0
4
+ Summary: Durable application alignment evaluations, evidence review, saved comparisons, and CI gates.
5
+ Author: Alignmenter
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://alignmenter.com
8
+ Project-URL: Repository, https://github.com/justinGrosvenor/alignmenter
9
+ Project-URL: Documentation, https://github.com/justinGrosvenor/alignmenter
10
+ Project-URL: Bug Tracker, https://github.com/justinGrosvenor/alignmenter/issues
11
+ Keywords: llm,evaluation,alignment,persona,safety,llm-judge
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Information Technology
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: typer<1,>=0.12
27
+ Requires-Dist: pydantic<3,>=2.5
28
+ Requires-Dist: pydantic-settings<3,>=2
29
+ Requires-Dist: openai<3,>=1.40
30
+ Requires-Dist: anthropic<1,>=0.40
31
+ Requires-Dist: pyyaml<7,>=6
32
+ Requires-Dist: tiktoken<1,>=0.7
33
+ Requires-Dist: requests<3,>=2.32
34
+ Provides-Extra: ml
35
+ Requires-Dist: torch<3,>=2; extra == "ml"
36
+ Requires-Dist: sentence-transformers<6,>=3; extra == "ml"
37
+ Requires-Dist: transformers<6,>=4.40; extra == "ml"
38
+ Provides-Extra: calibrate
39
+ Requires-Dist: scikit-learn<2,>=1.3; extra == "calibrate"
40
+ Requires-Dist: numpy<3,>=1.24; extra == "calibrate"
41
+ Provides-Extra: safety
42
+ Requires-Dist: alignmenter[ml]; extra == "safety"
43
+ Provides-Extra: all
44
+ Requires-Dist: alignmenter[calibrate,ml]; extra == "all"
45
+ Provides-Extra: dev
46
+ Requires-Dist: alignmenter[calibrate,ml]; extra == "dev"
47
+ Requires-Dist: pytest>=8; extra == "dev"
48
+ Requires-Dist: pytest-cov; extra == "dev"
49
+ Requires-Dist: ruff>=0.6; extra == "dev"
50
+ Requires-Dist: build; extra == "dev"
51
+ Requires-Dist: twine; extra == "dev"
52
+ Provides-Extra: test
53
+ Requires-Dist: pytest>=8; extra == "test"
54
+ Requires-Dist: pytest-cov; extra == "test"
55
+ Requires-Dist: ruff>=0.6; extra == "test"
56
+ Requires-Dist: build; extra == "test"
57
+ Requires-Dist: twine; extra == "test"
58
+ Provides-Extra: docs
59
+ Requires-Dist: mkdocs<2,>=1.6; extra == "docs"
60
+ Requires-Dist: mkdocs-material<10,>=9; extra == "docs"
61
+ Dynamic: license-file
62
+
63
+ # Alignmenter
64
+
65
+ Application alignment evaluations with saved evidence, repeatable release checks,
66
+ and a lightweight Python SDK and CLI.
67
+
68
+ ## Overview
69
+
70
+ Alignmenter 0.3 checks whether an assistant meets the commitments of its application:
71
+ uses the resources the user has, respects constraints, supports claims with supplied
72
+ evidence, and avoids dangerous advice. Capture answers once, evaluate them under
73
+ versioned criteria, compare a candidate with a baseline, and preserve human review.
74
+
75
+ - **Durable execution:** SQLite observations, frozen inputs, explicit recovery, and
76
+ shared judge reservations preserve partial work across interruptions.
77
+ - **Application-owned checks:** deterministic evaluator factories and typed metrics
78
+ work with the same grouping, reports, comparisons, and gates as builtins.
79
+ - **Evidence evaluation:** offline quantity traceability/citation checks and strict
80
+ judged faithfulness retain the claims and source quotes behind each outcome.
81
+ - **Release decisions:** matched case comparisons, explicit coverage, absolute and
82
+ regression gates, and consistent CLI/HTML/JSON/Markdown/JUnit results.
83
+ - **Human review:** append-only JSONL annotation exchange, adjudication, evaluator
84
+ agreement reports, and regression promotion with case lineage and split groups.
85
+ - **Local inspection:** offline HTML and portable read-only run archives; the core
86
+ install does not require torch or scikit-learn.
87
+
88
+ Missing work cannot produce a green release check. A draft specification cannot pass.
89
+ The legacy persona, authenticity, safety, stability, and calibration tools remain
90
+ available; new release integrations should use the durable workflow.
91
+
92
+ ## Quickstart
93
+
94
+ ```bash
95
+ pip install alignmenter
96
+ alignmenter --version
97
+ alignmenter init-suite --out evals/resource-task
98
+ alignmenter run-suite evals/resource-task/suite.yaml --out reports
99
+ ```
100
+
101
+ The installed example uses a local target and a deterministic resource constraint.
102
+ It needs no API key. The command prints the run directory, evaluation UUID, decision,
103
+ and artifact directory. Open its `index.html` to inspect evidence. Exit codes are
104
+ **0 pass, 2 fail, 3 inconclusive**. Exercise a deliberate failure with:
105
+
106
+ ```bash
107
+ ALIGNMENTER_DEMO_VARIANT=bad alignmenter run-suite evals/resource-task/suite.yaml --out reports
108
+ ```
109
+
110
+ To work from this checkout, including a release candidate before publication:
111
+
112
+ ```bash
113
+ python -m venv .venv
114
+ source .venv/bin/activate
115
+ pip install -e 'alignmenter[test,docs]'
116
+ ```
117
+
118
+ Python 3.10–3.14 are supported for the core package. Durable execution uses a local
119
+ POSIX coordinator; Windows and multi-host/network-filesystem execution are not
120
+ supported in 0.3. Optional `[ml]` and `[calibrate]` extras retain their upstream
121
+ platform requirements.
122
+
123
+ ```python
124
+ from alignmenter.sdk import run_suite, evaluation_summary
125
+
126
+ result = run_suite("evals/resource-task/suite.yaml", out_dir="reports")
127
+ summary = evaluation_summary(result["run_dir"], details=True)
128
+ ```
129
+
130
+ See the [release workflow](https://docs.alignmenter.com/guides/release-workflow/),
131
+ [SDK reference](https://docs.alignmenter.com/reference/sdk/), and
132
+ [0.3 migration guide](https://docs.alignmenter.com/guides/migration-0.3/).
133
+ In the repository, these sources are under `docs/guides/` and `docs/reference/`.
134
+
135
+ The example is an engineering fixture, not evidence of model quality. Atlas integration
136
+ fixtures preserve real failures, with product rubrics still marked draft. Actual judge
137
+ qualification needs independent human references and saved model outputs. AverCare
138
+ qualification awaits a selected application workflow. Hosted review, physical-device
139
+ replay, distributed budgets, and automatic optimization remain roadmap work.
140
+
141
+ ## Legacy persona documentation
142
+
143
+ The sections below describe the retained persona/scorer APIs. Their older scores,
144
+ reports, and scorer-local budgets do not use the new durable contracts. See the
145
+ linked migration guide when integrating them into release checks.
146
+
147
+ ## Legacy persona features
148
+
149
+ ### 🎯 Three-Dimensional Scoring
150
+
151
+ #### Authenticity
152
+ - **Embedding similarity**: Measures semantic alignment with persona examples
153
+ - **Trait model**: Logistic regression on linguistic features (trained via calibration)
154
+ - **Lexicon matching**: Enforces preferred/avoided vocabulary
155
+ - **Bootstrap CI**: Statistical confidence intervals for reliability
156
+
157
+ #### Safety
158
+ - **Keyword classifier**: Fast pattern matching for common violations
159
+ - **LLM judge**: GPT-4 as a safety oracle with budget controls
160
+ - **Offline classifier**: ProtectAI's distilled-safety-roberta (no API calls)
161
+ - **Fused scoring**: Weighted ensemble of rule-based + model-based signals
162
+ - **Adversarial testing**: Built-in safety traps in demo datasets
163
+
164
+ #### Stability
165
+ - **Cosine variance**: Detects semantic drift across conversation turns
166
+ - **Session clustering**: Identifies divergent response patterns
167
+ - **Temporal analysis**: Tracks consistency over time
168
+
169
+ ### 📊 Rich Reporting
170
+
171
+ - **Interactive HTML**: Grade-based report cards with charts (Chart.js)
172
+ - **JSON export**: Machine-readable results for CI/CD pipelines
173
+ - **CSV downloads**: Per-metric exports for spreadsheet analysis
174
+ - **Turn-level explorer**: Drill down into individual responses
175
+
176
+ ### 🔧 Production-Ready
177
+
178
+ - **Multi-provider support**: OpenAI, Anthropic, local (vLLM, Ollama)
179
+ - **Budget guardrails**: Halt runs at 90% of judge API budget
180
+ - **Cost projection**: Estimate expenses before execution
181
+ - **Reproducibility**: Logs Python version, model, seed, timestamps
182
+ - **PII sanitization**: Built-in scrubbing for production data
183
+
184
+ ### 🚀 Developer Experience
185
+
186
+ - **CLI-first**: Simple commands for evaluation, calibration, reporting
187
+ - **YAML configuration**: Declarative persona packs and run configs
188
+ - **Python API**: Programmatic access for custom workflows
189
+ - **Comprehensive tests**: 69+ unit tests with pytest
190
+ - **Type safety**: Full type hints throughout
191
+
192
+ ## Architecture
193
+
194
+ ```
195
+ ┌─────────────────────────────────────────────────────────────────┐
196
+ │ Alignmenter CLI │
197
+ │ alignmenter run / report / calibrate / bootstrap / sanitize │
198
+ └─────────────────────────────────────────────────────────────────┘
199
+ │
200
+ ▼
201
+ ┌─────────────────────────────────────────────────────────────────┐
202
+ │ Runner │
203
+ │ Orchestrates evaluation: load data → score → report │
204
+ └─────────────────────────────────────────────────────────────────┘
205
+ │
206
+ ┌───────────────────┼───────────────────┐
207
+ ▼ ▼ ▼
208
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
209
+ │ Authenticity │ │ Safety │ │ Stability │
210
+ │ Scorer │ │ Scorer │ │ Scorer │
211
+ └──────────────┘ └──────────────┘ └──────────────┘
212
+ │ │ │
213
+ │ │ │
214
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
215
+ │ Embeddings │ │ LLM Judge │ │ Cosine │
216
+ │ Trait Model │ │ Keywords │ │ Variance │
217
+ │ Lexicon │ │ Fusion │ │ Clustering │
218
+ └──────────────┘ └──────────────┘ └──────────────┘
219
+ │
220
+ ▼
221
+ ┌───────────────────────────────────────┐
222
+ │ Reporting Layer │
223
+ │ HTML / JSON / CSV / Interactive UI │
224
+ └───────────────────────────────────────┘
225
+ ```
226
+
227
+ ### Key Components
228
+
229
+ | Component | Purpose | Key Files |
230
+ |-----------|---------|-----------|
231
+ | **CLI** | Command-line interface | `src/alignmenter/cli.py` |
232
+ | **Runner** | Orchestration engine | `src/alignmenter/runner.py` |
233
+ | **Scorers** | Metric computation | `src/alignmenter/scorers/` |
234
+ | **Providers** | LLM/embedding backends | `src/alignmenter/providers/` |
235
+ | **Reporters** | Output generation | `src/alignmenter/reporting/` |
236
+ | **Datasets** | JSONL conversation data | `datasets/` |
237
+ | **Personas** | Brand voice definitions | `configs/persona/` |
238
+
239
+ ## 📚 Documentation
240
+
241
+ **Full documentation available at [docs.alignmenter.com](https://docs.alignmenter.com)**
242
+
243
+ Quick links:
244
+ - **[Quick Start Guide](https://docs.alignmenter.com/getting-started/quickstart/)** - Get started in 5 minutes
245
+ - **[Installation](https://docs.alignmenter.com/getting-started/installation/)** - Install and setup
246
+ - **[CLI Reference](https://docs.alignmenter.com/reference/cli/)** - Complete command reference
247
+ - **[Persona Guide](https://docs.alignmenter.com/guides/persona/)** - Configure your brand voice
248
+ - **[Calibration Guide](https://docs.alignmenter.com/guides/calibration/)** - Advanced calibration workflow
249
+ - **[Safety Guide](https://docs.alignmenter.com/guides/safety/)** - Offline safety classifier
250
+ - **[LLM Judges](https://docs.alignmenter.com/guides/llm-judges/)** - Qualitative analysis
251
+ - **[Contributing](https://docs.alignmenter.com/contributing/)** - How to contribute
252
+
253
+ ---
254
+
255
+ ## Case Studies
256
+
257
+ - **[Wendy's Twitter Voice](../docs/case-studies/wendys-twitter.md)** - End-to-end calibration example using the included case-study assets. *(Available when running from the source repo; not included in the PyPI wheel.)*
258
+
259
+ ---
260
+
261
+ ## Usage Examples
262
+
263
+ ### Evaluate Multiple Models
264
+
265
+ ```bash
266
+ # Compare GPT-4 vs Claude
267
+ alignmenter run \
268
+ --model openai:gpt-4 \
269
+ --compare anthropic:claude-3-5-sonnet-20241022 \
270
+ --dataset datasets/demo_conversations.jsonl \
271
+ --persona configs/persona/default.yaml
272
+ ```
273
+
274
+ ### Custom Judge and Embeddings
275
+
276
+ ```bash
277
+ # Use Claude as safety judge, local embeddings
278
+ alignmenter run \
279
+ --model openai:gpt-4o-mini \
280
+ --judge anthropic:claude-3-5-sonnet-20241022 \
281
+ --embedding sentence-transformer:all-MiniLM-L6-v2 \
282
+ --dataset datasets/demo_conversations.jsonl \
283
+ --persona configs/persona/default.yaml
284
+ ```
285
+
286
+ ### Bootstrap Synthetic Dataset
287
+
288
+ ```bash
289
+ # Generate 50 conversations with adversarial traps
290
+ alignmenter bootstrap-dataset \
291
+ --out datasets/my_test.jsonl \
292
+ --sessions 50 \
293
+ --safety-trap-ratio 0.15 \
294
+ --brand-trap-ratio 0.20 \
295
+ --seed 42
296
+ ```
297
+
298
+ ### Calibrate Persona Traits
299
+
300
+ ```bash
301
+ # Train trait model from labeled data
302
+ alignmenter calibrate-persona \
303
+ --persona-path configs/persona/mybot.yaml \
304
+ --dataset annotations.jsonl \
305
+ --out configs/persona/mybot.traits.json \
306
+ --epochs 300
307
+ ```
308
+
309
+ ### Sanitize Production Data
310
+
311
+ ```bash
312
+ # Remove PII before evaluation
313
+ alignmenter dataset sanitize prod_logs.jsonl \
314
+ --out datasets/sanitized.jsonl \
315
+ --no-use-hashing
316
+ ```
317
+
318
+ ## Persona Configuration
319
+
320
+ Define your brand voice in YAML:
321
+
322
+ ```yaml
323
+ # configs/persona/mybot.yaml
324
+ id: mybot
325
+ name: "MyBot Assistant"
326
+ description: "Professional, evidence-driven, technical"
327
+
328
+ voice:
329
+ tone: ["professional", "precise", "measured"]
330
+ formality: "business_casual"
331
+
332
+ # Preferred vocabulary
333
+ lexicon:
334
+ preferred:
335
+ - "baseline"
336
+ - "signal"
337
+ - "alignment"
338
+ - "evidence-based"
339
+ avoided:
340
+ - "lol"
341
+ - "bro"
342
+ - "hype"
343
+ - "vibes"
344
+
345
+ # Example on-brand responses (for embedding similarity)
346
+ examples:
347
+ - "Our baseline analysis indicates a 15% improvement in alignment metrics."
348
+ - "The signal-to-noise ratio suggests this approach is viable."
349
+ - "Let's establish a clear baseline before proceeding."
350
+
351
+ # Trait model weights (generated by calibration)
352
+ traits:
353
+ weights: [0.12, -0.34, 0.08, ...] # Learned from annotations
354
+ vocabulary: ["baseline", "signal", ...]
355
+ ```
356
+
357
+ ## Legacy API usage
358
+
359
+ `Runner` coordinates transcript preparation, scoring, and report generation.
360
+ It takes a `RunConfig` plus a list of scorers, and `execute()` returns the
361
+ path to the timestamped report directory (JSON + HTML are written for you).
362
+
363
+ Runs now persist source snapshots and each captured answer before scoring. If execution
364
+ fails, `runner.run_dir` identifies the saved work. Use `alignmenter status RUN_DIRECTORY`
365
+ and `alignmenter export-transcripts RUN_DIRECTORY --out recovered.jsonl` to inspect and
366
+ recover committed records. `runner.capture()` and `alignmenter capture` save answers
367
+ without scoring; `alignmenter resume` continues compatible capture with explicit adapter
368
+ recovery contracts. See the [durable run guide](../docs/guides/durable-runs.md) and
369
+ [capture/recovery guide](../docs/guides/capture-recovery.md) for the contracts and limits.
370
+
371
+ `alignmenter evaluate RUN_DIRECTORY --spec rubrics.yaml --judge-factory module:factory
372
+ --max-judge-calls 20` evaluates saved answers with versioned behavior criteria, a shared
373
+ durable judge budget, and reusable replies/verdicts. `alignmenter evaluation-status
374
+ RUN_DIRECTORY --details` exports the saved evidence and decisions without more judge
375
+ calls. This path also supports [grounding and faithfulness](../docs/guides/grounding-faithfulness.md)
376
+ with typed evidence, explicit missing-data states, and saved metrics. A grounding-only
377
+ spec needs no judge factory or budget. Existing `run` scorers retain their legacy behavior;
378
+ see [durable evaluations](../docs/guides/durable-evaluations.md) for the accounting boundary.
379
+
380
+ ```python
381
+ import json
382
+ from pathlib import Path
383
+
384
+ from alignmenter.runner import RunConfig, Runner
385
+ from alignmenter.scorers.authenticity import AuthenticityScorer
386
+ from alignmenter.scorers.safety import SafetyScorer
387
+ from alignmenter.scorers.stability import StabilityScorer
388
+
389
+ config = RunConfig(
390
+ model="openai:gpt-4o-mini",
391
+ dataset_path=Path("datasets/demo_conversations.jsonl"),
392
+ persona_path=Path("configs/persona/default.yaml"),
393
+ )
394
+
395
+ # Pass a judge to AuthenticityScorer/SafetyScorer to blend LLM judgment in;
396
+ # omit it (as here) for a fully offline, deterministic run.
397
+ scorers = [
398
+ AuthenticityScorer(persona_path=config.persona_path, embedding="hashed"),
399
+ SafetyScorer(keyword_path=Path("configs/safety_keywords.yaml")),
400
+ StabilityScorer(embedding="hashed"),
401
+ ]
402
+
403
+ # generate_transcripts=False reuses recorded transcripts (no provider calls).
404
+ runner = Runner(config, scorers, generate_transcripts=False)
405
+ run_dir = runner.execute() # -> Path to reports/<timestamp>_<run_id>/
406
+
407
+ results = json.loads((run_dir / "results.json").read_text())
408
+ primary = results["scores"]["primary"]
409
+ auth = primary["authenticity"]
410
+ print(f"Authenticity: {auth['mean']:.3f} (basis: {auth['basis']})")
411
+ print(f"Safety: {primary['safety']['score']:.3f}")
412
+ print(f"Stability: {primary['stability']['stability']:.3f}")
413
+ ```
414
+
415
+ ## Legacy CI integration
416
+
417
+ ```yaml
418
+ # .github/workflows/eval.yml
419
+ name: Persona Evaluation
420
+
421
+ on: [push, pull_request]
422
+
423
+ jobs:
424
+ evaluate:
425
+ runs-on: ubuntu-latest
426
+ steps:
427
+ - uses: actions/checkout@v3
428
+ - uses: actions/setup-python@v4
429
+ with:
430
+ python-version: '3.11'
431
+
432
+ - name: Install Alignmenter
433
+ run: pip install alignmenter
434
+
435
+ - name: Run Evaluation
436
+ env:
437
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
438
+ run: |
439
+ alignmenter run \
440
+ --model openai:gpt-4o-mini \
441
+ --dataset datasets/ci_test.jsonl \
442
+ --persona configs/persona/default.yaml \
443
+ --judge-budget 100
444
+
445
+ - name: Upload Report
446
+ uses: actions/upload-artifact@v3
447
+ with:
448
+ name: evaluation-report
449
+ path: reports/
450
+ ```
451
+
452
+ ## Development
453
+
454
+ ### Running Tests
455
+
456
+ ```bash
457
+ # All tests
458
+ pytest
459
+
460
+ # With coverage
461
+ pytest --cov=src/alignmenter --cov-report=html
462
+
463
+ # Specific test file
464
+ pytest tests/test_scorers.py -v
465
+ ```
466
+
467
+ ### Code Quality
468
+
469
+ ```bash
470
+ # Type checking
471
+ mypy src/
472
+
473
+ # Linting
474
+ ruff check src/
475
+
476
+ # Formatting
477
+ black src/ tests/
478
+ ```
479
+
480
+ ### Local Development
481
+
482
+ ```bash
483
+ # Install in editable mode with dev dependencies
484
+ pip install -e .[dev]
485
+
486
+ # Run from source
487
+ python -m alignmenter.cli run --help
488
+
489
+ # Generate report from last run
490
+ make report-last
491
+ ```
492
+
493
+ ## Earlier persona roadmap
494
+
495
+ ### Completed ✅
496
+ - Three-dimensional scoring (authenticity, safety, stability)
497
+ - Multi-provider support (OpenAI, Anthropic, local models)
498
+ - HTML report cards with interactive charts
499
+ - Offline safety classifier (distilled-safety-roberta)
500
+ - LLM judges for qualitative analysis
501
+ - Budget guardrails and cost tracking
502
+ - PII sanitization tools
503
+ - Calibration workflow and diagnostics
504
+
505
+ ### In Progress 🚧
506
+ - Multi-language support (non-English personas)
507
+ - Batch processing optimizations
508
+ - Additional embedding providers
509
+
510
+ ### Future Considerations 💭
511
+ - Synthetic test case generation
512
+ - Custom metric plugins
513
+ - Advanced trait models (neural networks)
514
+
515
+ ## Contributing
516
+
517
+ We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
518
+
519
+ **Areas we'd love help with:**
520
+ - Additional persona packs (different brand voices)
521
+ - Language support beyond English
522
+ - Integration with other LLM providers
523
+ - Performance optimizations for large datasets
524
+
525
+ ## License
526
+
527
+ Apache License 2.0 - see [LICENSE](LICENSE) for details.
528
+
529
+ ## Citation
530
+
531
+ If you use Alignmenter in research, please cite:
532
+
533
+ ```bibtex
534
+ @software{alignmenter2024,
535
+ title={Alignmenter: A Framework for Persona-Aligned Conversational AI Evaluation},
536
+ author={Alignmenter Contributors},
537
+ year={2025},
538
+ url={https://github.com/justinGrosvenor/alignmenter},
539
+ license={Apache-2.0}
540
+ }
541
+ ```
542
+
543
+ ## Support
544
+
545
+ - **Documentation**: [docs.alignmenter.com](https://docs.alignmenter.com)
546
+ - **Issues**: [GitHub Issues](https://github.com/justinGrosvenor/alignmenter/issues)
547
+ - **Discussions**: [GitHub Discussions](https://github.com/justinGrosvenor/alignmenter/discussions)
548
+
549
+ ---
550
+
551
+ <p align="center">
552
+ Made with ❤️ by the Alignmenter team
553
+ </p>