isnad 1.0.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.
- isnad-1.0.0/PKG-INFO +194 -0
- isnad-1.0.0/README.md +164 -0
- isnad-1.0.0/pyproject.toml +86 -0
- isnad-1.0.0/src/isnad/__init__.py +97 -0
- isnad-1.0.0/src/isnad/chain.py +201 -0
- isnad-1.0.0/src/isnad/corroboration.py +272 -0
- isnad-1.0.0/src/isnad/db.py +84 -0
- isnad-1.0.0/src/isnad/grading.py +161 -0
- isnad-1.0.0/src/isnad/matn.py +198 -0
- isnad-1.0.0/src/isnad/matrix.py +112 -0
- isnad-1.0.0/src/isnad/models.py +349 -0
- isnad-1.0.0/src/isnad/registry.py +452 -0
- isnad-1.0.0/src/isnad/types.py +371 -0
isnad-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: isnad
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Isnād–Rijāl framework for claim-level provenance in multi-agent knowledge systems
|
|
5
|
+
Keywords: provenance,multi-agent,trust,knowledge-base,epistemology,isnad
|
|
6
|
+
Author: Ali Zahid Raja
|
|
7
|
+
Author-email: Ali Zahid Raja <alizahidrajaa@gmail.com>
|
|
8
|
+
License: Apache-2.0
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Requires-Dist: sqlalchemy>=2.0,<3.0
|
|
15
|
+
Requires-Dist: pydantic>=2.0,<3.0
|
|
16
|
+
Requires-Dist: alembic>=1.13,<2.0
|
|
17
|
+
Requires-Dist: psycopg2-binary>=2.9,<3.0
|
|
18
|
+
Requires-Dist: isnad[dev,anthropic] ; extra == 'all'
|
|
19
|
+
Requires-Dist: anthropic>=0.40 ; extra == 'anthropic'
|
|
20
|
+
Requires-Dist: pytest>=8.0 ; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest-asyncio>=0.24 ; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.5 ; extra == 'dev'
|
|
23
|
+
Requires-Dist: mypy>=1.11 ; extra == 'dev'
|
|
24
|
+
Requires-Dist: pre-commit>=3.8 ; extra == 'dev'
|
|
25
|
+
Requires-Python: >=3.12
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Provides-Extra: anthropic
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# Isnād–Rijāl Framework
|
|
32
|
+
|
|
33
|
+
**Grade the narrators, not just log them.** Claim-level provenance for multi-agent knowledge systems.
|
|
34
|
+
|
|
35
|
+
[](https://github.com/alizahidraja/isnad/actions/workflows/ci.yml)
|
|
36
|
+
[](https://www.python.org/)
|
|
37
|
+
[](LICENSE)
|
|
38
|
+
[](https://doi.org/10.5281/zenodo.21211291)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 60-second quickstart
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from isnad import Registry, Chain, ChainLinkSpec, grade_chain, decide
|
|
46
|
+
from isnad.types import NarratorGrade, TransformType, ContentVerdict
|
|
47
|
+
from isnad.matn import DeterministicRuleCritic
|
|
48
|
+
|
|
49
|
+
# Build a transmission chain: source → scraper → model
|
|
50
|
+
chain = Chain([
|
|
51
|
+
ChainLinkSpec("openstax-v3", 0, domain="physics"),
|
|
52
|
+
ChainLinkSpec("pdf-scraper", 1, transform_type=TransformType.DESTRUCTIVE),
|
|
53
|
+
ChainLinkSpec("ingest-model", 2, transform_type=TransformType.GENERATIVE),
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
# Two narrators are ungraded → HASAN tier
|
|
57
|
+
reg = Registry()
|
|
58
|
+
reg.register("openstax-v3", "physics", grade=NarratorGrade.RELIABLE)
|
|
59
|
+
reg.register("pdf-scraper", "physics", grade=NarratorGrade.UNGRADED)
|
|
60
|
+
reg.register("ingest-model", "physics", grade=NarratorGrade.UNGRADED)
|
|
61
|
+
|
|
62
|
+
# Grade the chain
|
|
63
|
+
grades = [reg.get_grade(l.narrator_id, l.domain) for l in chain.links]
|
|
64
|
+
transforms = [l.transform_type for l in chain.links]
|
|
65
|
+
cg = grade_chain(grades, transforms, is_complete=True)
|
|
66
|
+
|
|
67
|
+
# Content criticism (fully decoupled from chain grading)
|
|
68
|
+
cv = DeterministicRuleCritic().evaluate("p = h/λ", "p = h/lambda", ["p = mv"])
|
|
69
|
+
|
|
70
|
+
# Decision matrix: HASAN × CONTRADICTION → REVIEW
|
|
71
|
+
action = decide(cg, cv)
|
|
72
|
+
print(f"Chain: {cg.value.upper()} | Content: {cv.value} | Action: {action.value}")
|
|
73
|
+
# Output: Chain: HASAN | Content: CONTRADICTION | Action: review
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
📄 **Paper:** ["Grading the Narrators"](https://doi.org/10.5281/zenodo.21211291) — Ali Zahid Raja (2026)
|
|
77
|
+
📋 **Companion gist:** [Schema & design notes](https://gist.github.com/alizahidraja/56beaadf493976182f38aa602b8958e2)
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Install
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/alizahidraja/isnad.git && cd isnad
|
|
85
|
+
make install # uv sync
|
|
86
|
+
make test # 90 tests, zero config, SQLite fallback
|
|
87
|
+
make demo # Paper's worked example (§4.5)
|
|
88
|
+
make check # lint + type-check + test
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
No database required for pure-logic tests. PostgreSQL is optional (`docker compose up`, set `ISNAD_DATABASE_URL`).
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## What problem does this solve?
|
|
96
|
+
|
|
97
|
+
In modern AI pipelines, a factual claim passes through many hands — a scraper extracts it, a model compiles it, another serves it — and each hand can drop, distort, or invent. Existing provenance tools record *what* happened. They don't grade *who* transformed the claim, so they can't tell you how much to trust the result.
|
|
98
|
+
|
|
99
|
+
This framework adapts classical Islamic hadith transmission science — one of history's most rigorous pre-modern epistemologies — into a Python library for AI systems. The core insight: **the trustworthiness of a claim is a function of the graded reliability of every individual who transmitted it**. Claims carry complete chains (isnād); transmitters are graded in a living registry (rijāl); chains are graded by their weakest link; independent corroboration can upgrade; and content is criticized independently of transmission quality.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Concept → module mapping
|
|
104
|
+
|
|
105
|
+
| Concept | What it does | Module |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| **isnād** (chain) | Ordered, gap-checked transmission chain per claim | `isnad/chain.py` |
|
|
108
|
+
| **rijāl** (registry) | Graded narrator store per (narrator, domain) | `isnad/registry.py` |
|
|
109
|
+
| **jarḥ–taʿdīl** | Evidence-driven state machine for narrator grades | `isnad/registry.py` |
|
|
110
|
+
| **ittiṣāl/munqaṭiʿ** | Completeness as epistemic property (gap → DAIF) | `isnad/chain.py` |
|
|
111
|
+
| **Weakest-link grading** | Chain grade = refined minimum over narrators | `isnad/grading.py` |
|
|
112
|
+
| **mutābaʿāt** | Independent-chain corroboration with correlation detection | `isnad/corroboration.py` |
|
|
113
|
+
| **matn criticism** | Content evaluated independently of chain quality | `isnad/matn.py` |
|
|
114
|
+
| **Decision matrix** | 4×2 (chain × content) → action router | `isnad/matrix.py` |
|
|
115
|
+
| **ʿadālah / ḍabṭ** | Integrity and precision as two distinct axes | `isnad/types.py` |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Pluggable strategies
|
|
120
|
+
|
|
121
|
+
The paper deliberately leaves certain transition arithmetic open (§4.2/§4.3). These are exposed as swappable interfaces:
|
|
122
|
+
|
|
123
|
+
| Strategy | Protocol | Default | What it decides |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| `GradingStrategy` | `isnad/types.py` | `RefinedWeakestLink` | How link grades combine into a chain grade |
|
|
126
|
+
| `TransitionPolicy` | `isnad/types.py` | `ThresholdTransitionPolicy` | How evidence moves narrators between ordinal states |
|
|
127
|
+
| `CorroborationPolicy` | `isnad/types.py` | `CappedCorroborationPolicy` | How independent chains upgrade a claim |
|
|
128
|
+
| `CorrelationDetector` | `isnad/types.py` | `SharedLineageDetector` | Whether two chains are truly independent |
|
|
129
|
+
| `ContentCritic` | `isnad/types.py` | `DeterministicRuleCritic` | Content contradiction detection |
|
|
130
|
+
|
|
131
|
+
**Swap one in one line:**
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from isnad import grade_chain, RefinedWeakestLink
|
|
135
|
+
|
|
136
|
+
class MyStrategy:
|
|
137
|
+
def compute_chain_grade(self, grades, transforms, is_complete, *, corroboration_support=False):
|
|
138
|
+
# Your logic here
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
result = grade_chain(grades, transforms, is_complete=True, strategy=MyStrategy())
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Status — what this does and does not validate
|
|
147
|
+
|
|
148
|
+
**This implements:** the framework's architecture, grading logic, and all pluggable strategy interfaces. It passes 90+ tests enforcing every epistemic commitment from the paper, including the paper's worked example (§4.5) as an end-to-end integration test.
|
|
149
|
+
|
|
150
|
+
**This does NOT constitute:** the end-to-end empirical validation (gated-vs-ungated served-error study) that the paper scopes as future work (§8). The registry bootstrapping, transition-policy thresholds, and corroboration arithmetic are reference defaults — not empirically calibrated values. Deployers should run the §8 experiment against their own pipelines.
|
|
151
|
+
|
|
152
|
+
**Reference stubs** are docstring-labeled:
|
|
153
|
+
- `DeterministicRuleCritic` — hardcoded pattern matching; production needs semantic/LLM critic.
|
|
154
|
+
- `LLMCritic` — reference Anthropic integration; needs batching, caching, ensemble for production.
|
|
155
|
+
- `SharedLineageDetector` — exact-match heuristics; production needs structured model lineage data.
|
|
156
|
+
- Seed-grade bootstrapping — designed but not yet implemented (see §7 of paper).
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Contributing
|
|
161
|
+
|
|
162
|
+
See [`CONTRIBUTING.md`](CONTRIBUTING.md). Especially welcome:
|
|
163
|
+
|
|
164
|
+
1. **New `CorrelationDetector`** using embedding similarity or model-card lineage data.
|
|
165
|
+
2. **Seed-grade bootstrapper** that initializes narrator grades from published benchmark accuracies.
|
|
166
|
+
3. **Domain-specific `ContentCritic`** with formula canonicalization (physics, medicine, law).
|
|
167
|
+
4. **Calibrated `TransitionPolicy`** from your own pipeline's §8 experiment data.
|
|
168
|
+
5. **Pipeline adapters** for LangChain, CrewAI, or Autogen tracing.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Citation
|
|
173
|
+
|
|
174
|
+
If you use this software, cite the paper:
|
|
175
|
+
|
|
176
|
+
```bibtex
|
|
177
|
+
@software{raja2026isnad,
|
|
178
|
+
author = {Ali Zahid Raja},
|
|
179
|
+
title = {Isnād–Rijāl Framework: Claim-Level Provenance in Multi-Agent Knowledge Systems},
|
|
180
|
+
year = 2026,
|
|
181
|
+
doi = {10.5281/zenodo.21211291},
|
|
182
|
+
url = {https://doi.org/10.5281/zenodo.21211291},
|
|
183
|
+
orcid = {0009-0003-7875-4590},
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
> A dedicated software DOI will be added after the first Zenodo release.
|
|
188
|
+
> GitHub's "Cite this repository" button is powered by [`CITATION.cff`](CITATION.cff).
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
Code: [Apache 2.0](LICENSE) · Paper & docs: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
|
isnad-1.0.0/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Isnād–Rijāl Framework
|
|
2
|
+
|
|
3
|
+
**Grade the narrators, not just log them.** Claim-level provenance for multi-agent knowledge systems.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/alizahidraja/isnad/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.python.org/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://doi.org/10.5281/zenodo.21211291)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 60-second quickstart
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
from isnad import Registry, Chain, ChainLinkSpec, grade_chain, decide
|
|
16
|
+
from isnad.types import NarratorGrade, TransformType, ContentVerdict
|
|
17
|
+
from isnad.matn import DeterministicRuleCritic
|
|
18
|
+
|
|
19
|
+
# Build a transmission chain: source → scraper → model
|
|
20
|
+
chain = Chain([
|
|
21
|
+
ChainLinkSpec("openstax-v3", 0, domain="physics"),
|
|
22
|
+
ChainLinkSpec("pdf-scraper", 1, transform_type=TransformType.DESTRUCTIVE),
|
|
23
|
+
ChainLinkSpec("ingest-model", 2, transform_type=TransformType.GENERATIVE),
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
# Two narrators are ungraded → HASAN tier
|
|
27
|
+
reg = Registry()
|
|
28
|
+
reg.register("openstax-v3", "physics", grade=NarratorGrade.RELIABLE)
|
|
29
|
+
reg.register("pdf-scraper", "physics", grade=NarratorGrade.UNGRADED)
|
|
30
|
+
reg.register("ingest-model", "physics", grade=NarratorGrade.UNGRADED)
|
|
31
|
+
|
|
32
|
+
# Grade the chain
|
|
33
|
+
grades = [reg.get_grade(l.narrator_id, l.domain) for l in chain.links]
|
|
34
|
+
transforms = [l.transform_type for l in chain.links]
|
|
35
|
+
cg = grade_chain(grades, transforms, is_complete=True)
|
|
36
|
+
|
|
37
|
+
# Content criticism (fully decoupled from chain grading)
|
|
38
|
+
cv = DeterministicRuleCritic().evaluate("p = h/λ", "p = h/lambda", ["p = mv"])
|
|
39
|
+
|
|
40
|
+
# Decision matrix: HASAN × CONTRADICTION → REVIEW
|
|
41
|
+
action = decide(cg, cv)
|
|
42
|
+
print(f"Chain: {cg.value.upper()} | Content: {cv.value} | Action: {action.value}")
|
|
43
|
+
# Output: Chain: HASAN | Content: CONTRADICTION | Action: review
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
📄 **Paper:** ["Grading the Narrators"](https://doi.org/10.5281/zenodo.21211291) — Ali Zahid Raja (2026)
|
|
47
|
+
📋 **Companion gist:** [Schema & design notes](https://gist.github.com/alizahidraja/56beaadf493976182f38aa602b8958e2)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/alizahidraja/isnad.git && cd isnad
|
|
55
|
+
make install # uv sync
|
|
56
|
+
make test # 90 tests, zero config, SQLite fallback
|
|
57
|
+
make demo # Paper's worked example (§4.5)
|
|
58
|
+
make check # lint + type-check + test
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
No database required for pure-logic tests. PostgreSQL is optional (`docker compose up`, set `ISNAD_DATABASE_URL`).
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## What problem does this solve?
|
|
66
|
+
|
|
67
|
+
In modern AI pipelines, a factual claim passes through many hands — a scraper extracts it, a model compiles it, another serves it — and each hand can drop, distort, or invent. Existing provenance tools record *what* happened. They don't grade *who* transformed the claim, so they can't tell you how much to trust the result.
|
|
68
|
+
|
|
69
|
+
This framework adapts classical Islamic hadith transmission science — one of history's most rigorous pre-modern epistemologies — into a Python library for AI systems. The core insight: **the trustworthiness of a claim is a function of the graded reliability of every individual who transmitted it**. Claims carry complete chains (isnād); transmitters are graded in a living registry (rijāl); chains are graded by their weakest link; independent corroboration can upgrade; and content is criticized independently of transmission quality.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Concept → module mapping
|
|
74
|
+
|
|
75
|
+
| Concept | What it does | Module |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| **isnād** (chain) | Ordered, gap-checked transmission chain per claim | `isnad/chain.py` |
|
|
78
|
+
| **rijāl** (registry) | Graded narrator store per (narrator, domain) | `isnad/registry.py` |
|
|
79
|
+
| **jarḥ–taʿdīl** | Evidence-driven state machine for narrator grades | `isnad/registry.py` |
|
|
80
|
+
| **ittiṣāl/munqaṭiʿ** | Completeness as epistemic property (gap → DAIF) | `isnad/chain.py` |
|
|
81
|
+
| **Weakest-link grading** | Chain grade = refined minimum over narrators | `isnad/grading.py` |
|
|
82
|
+
| **mutābaʿāt** | Independent-chain corroboration with correlation detection | `isnad/corroboration.py` |
|
|
83
|
+
| **matn criticism** | Content evaluated independently of chain quality | `isnad/matn.py` |
|
|
84
|
+
| **Decision matrix** | 4×2 (chain × content) → action router | `isnad/matrix.py` |
|
|
85
|
+
| **ʿadālah / ḍabṭ** | Integrity and precision as two distinct axes | `isnad/types.py` |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Pluggable strategies
|
|
90
|
+
|
|
91
|
+
The paper deliberately leaves certain transition arithmetic open (§4.2/§4.3). These are exposed as swappable interfaces:
|
|
92
|
+
|
|
93
|
+
| Strategy | Protocol | Default | What it decides |
|
|
94
|
+
|---|---|---|---|
|
|
95
|
+
| `GradingStrategy` | `isnad/types.py` | `RefinedWeakestLink` | How link grades combine into a chain grade |
|
|
96
|
+
| `TransitionPolicy` | `isnad/types.py` | `ThresholdTransitionPolicy` | How evidence moves narrators between ordinal states |
|
|
97
|
+
| `CorroborationPolicy` | `isnad/types.py` | `CappedCorroborationPolicy` | How independent chains upgrade a claim |
|
|
98
|
+
| `CorrelationDetector` | `isnad/types.py` | `SharedLineageDetector` | Whether two chains are truly independent |
|
|
99
|
+
| `ContentCritic` | `isnad/types.py` | `DeterministicRuleCritic` | Content contradiction detection |
|
|
100
|
+
|
|
101
|
+
**Swap one in one line:**
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from isnad import grade_chain, RefinedWeakestLink
|
|
105
|
+
|
|
106
|
+
class MyStrategy:
|
|
107
|
+
def compute_chain_grade(self, grades, transforms, is_complete, *, corroboration_support=False):
|
|
108
|
+
# Your logic here
|
|
109
|
+
...
|
|
110
|
+
|
|
111
|
+
result = grade_chain(grades, transforms, is_complete=True, strategy=MyStrategy())
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Status — what this does and does not validate
|
|
117
|
+
|
|
118
|
+
**This implements:** the framework's architecture, grading logic, and all pluggable strategy interfaces. It passes 90+ tests enforcing every epistemic commitment from the paper, including the paper's worked example (§4.5) as an end-to-end integration test.
|
|
119
|
+
|
|
120
|
+
**This does NOT constitute:** the end-to-end empirical validation (gated-vs-ungated served-error study) that the paper scopes as future work (§8). The registry bootstrapping, transition-policy thresholds, and corroboration arithmetic are reference defaults — not empirically calibrated values. Deployers should run the §8 experiment against their own pipelines.
|
|
121
|
+
|
|
122
|
+
**Reference stubs** are docstring-labeled:
|
|
123
|
+
- `DeterministicRuleCritic` — hardcoded pattern matching; production needs semantic/LLM critic.
|
|
124
|
+
- `LLMCritic` — reference Anthropic integration; needs batching, caching, ensemble for production.
|
|
125
|
+
- `SharedLineageDetector` — exact-match heuristics; production needs structured model lineage data.
|
|
126
|
+
- Seed-grade bootstrapping — designed but not yet implemented (see §7 of paper).
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Contributing
|
|
131
|
+
|
|
132
|
+
See [`CONTRIBUTING.md`](CONTRIBUTING.md). Especially welcome:
|
|
133
|
+
|
|
134
|
+
1. **New `CorrelationDetector`** using embedding similarity or model-card lineage data.
|
|
135
|
+
2. **Seed-grade bootstrapper** that initializes narrator grades from published benchmark accuracies.
|
|
136
|
+
3. **Domain-specific `ContentCritic`** with formula canonicalization (physics, medicine, law).
|
|
137
|
+
4. **Calibrated `TransitionPolicy`** from your own pipeline's §8 experiment data.
|
|
138
|
+
5. **Pipeline adapters** for LangChain, CrewAI, or Autogen tracing.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Citation
|
|
143
|
+
|
|
144
|
+
If you use this software, cite the paper:
|
|
145
|
+
|
|
146
|
+
```bibtex
|
|
147
|
+
@software{raja2026isnad,
|
|
148
|
+
author = {Ali Zahid Raja},
|
|
149
|
+
title = {Isnād–Rijāl Framework: Claim-Level Provenance in Multi-Agent Knowledge Systems},
|
|
150
|
+
year = 2026,
|
|
151
|
+
doi = {10.5281/zenodo.21211291},
|
|
152
|
+
url = {https://doi.org/10.5281/zenodo.21211291},
|
|
153
|
+
orcid = {0009-0003-7875-4590},
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
> A dedicated software DOI will be added after the first Zenodo release.
|
|
158
|
+
> GitHub's "Cite this repository" button is powered by [`CITATION.cff`](CITATION.cff).
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
Code: [Apache 2.0](LICENSE) · Paper & docs: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "isnad"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Isnād–Rijāl framework for claim-level provenance in multi-agent knowledge systems"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Ali Zahid Raja", email = "alizahidrajaa@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
license = { text = "Apache-2.0" }
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
keywords = ["provenance", "multi-agent", "trust", "knowledge-base", "epistemology", "isnad"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Intended Audience :: Science/Research",
|
|
15
|
+
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"sqlalchemy>=2.0,<3.0",
|
|
22
|
+
"pydantic>=2.0,<3.0",
|
|
23
|
+
"alembic>=1.13,<2.0",
|
|
24
|
+
"psycopg2-binary>=2.9,<3.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
dev = [
|
|
29
|
+
"pytest>=8.0",
|
|
30
|
+
"pytest-asyncio>=0.24",
|
|
31
|
+
"ruff>=0.5",
|
|
32
|
+
"mypy>=1.11",
|
|
33
|
+
"pre-commit>=3.8",
|
|
34
|
+
]
|
|
35
|
+
anthropic = [
|
|
36
|
+
"anthropic>=0.40",
|
|
37
|
+
]
|
|
38
|
+
all = [
|
|
39
|
+
"isnad[dev,anthropic]",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
isnad = "isnad.cli:main"
|
|
44
|
+
|
|
45
|
+
[build-system]
|
|
46
|
+
requires = ["uv_build>=0.11.25,<0.12.0"]
|
|
47
|
+
build-backend = "uv_build"
|
|
48
|
+
|
|
49
|
+
[tool.ruff]
|
|
50
|
+
target-version = "py312"
|
|
51
|
+
line-length = 100
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint]
|
|
54
|
+
select = ["E", "F", "I", "N", "W", "UP", "B", "C4", "SIM"]
|
|
55
|
+
|
|
56
|
+
[tool.ruff.format]
|
|
57
|
+
quote-style = "double"
|
|
58
|
+
indent-style = "space"
|
|
59
|
+
|
|
60
|
+
[tool.mypy]
|
|
61
|
+
strict = true
|
|
62
|
+
python_version = "3.12"
|
|
63
|
+
warn_unreachable = true
|
|
64
|
+
warn_unused_ignores = true
|
|
65
|
+
|
|
66
|
+
[[tool.mypy.overrides]]
|
|
67
|
+
module = "sqlalchemy.*"
|
|
68
|
+
ignore_missing_imports = true
|
|
69
|
+
|
|
70
|
+
[[tool.mypy.overrides]]
|
|
71
|
+
module = "anthropic"
|
|
72
|
+
ignore_missing_imports = true
|
|
73
|
+
|
|
74
|
+
[tool.pytest.ini_options]
|
|
75
|
+
testpaths = ["tests"]
|
|
76
|
+
pythonpath = ["src"]
|
|
77
|
+
asyncio_mode = "auto"
|
|
78
|
+
|
|
79
|
+
[dependency-groups]
|
|
80
|
+
dev = [
|
|
81
|
+
"mypy>=2.1.0",
|
|
82
|
+
"pytest>=9.1.1",
|
|
83
|
+
"pytest-asyncio>=1.4.0",
|
|
84
|
+
"pytest-cov>=7.1.0",
|
|
85
|
+
"ruff>=0.15.20",
|
|
86
|
+
]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Isnād–Rijāl Framework.
|
|
2
|
+
|
|
3
|
+
Claim-level provenance for multi-agent knowledge systems, adapting classical
|
|
4
|
+
hadith-science methodology to grade transmitters (agents, models, scrapers)
|
|
5
|
+
rather than merely logging execution traces.
|
|
6
|
+
|
|
7
|
+
Quickstart (15 lines)::
|
|
8
|
+
|
|
9
|
+
from isnad import Registry, Chain, ChainLinkSpec, grade_chain, decide
|
|
10
|
+
from isnad.types import NarratorGrade, TransformType, ContentVerdict
|
|
11
|
+
from isnad.matn import DeterministicRuleCritic
|
|
12
|
+
|
|
13
|
+
chain = Chain([ChainLinkSpec("src", 0), ChainLinkSpec("model-v1", 1)])
|
|
14
|
+
reg = Registry()
|
|
15
|
+
reg.register("src", "physics", grade=NarratorGrade.RELIABLE)
|
|
16
|
+
reg.register("model-v1", "physics", grade=NarratorGrade.UNGRADED)
|
|
17
|
+
grades = [reg.get_grade(l.narrator_id, l.domain) for l in chain.links]
|
|
18
|
+
transforms = [l.transform_type for l in chain.links]
|
|
19
|
+
cg = grade_chain(grades, transforms, is_complete=chain.is_complete)
|
|
20
|
+
cv = DeterministicRuleCritic().evaluate("p=mv", "p=mv", ["p=h/lambda"])
|
|
21
|
+
action = decide(cg, cv)
|
|
22
|
+
print(f"Grade: {cg.value}, Verdict: {cv.value}, Action: {action.value}")
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
__version__ = "1.0.0"
|
|
26
|
+
__author__ = "Ali Zahid Raja"
|
|
27
|
+
|
|
28
|
+
# Public API — re-exports for user convenience
|
|
29
|
+
# ruff: noqa: F401 (these are intentional re-exports)
|
|
30
|
+
|
|
31
|
+
from isnad.chain import Chain, ChainLinkSpec, make_claim_id, normalize_claim_text
|
|
32
|
+
from isnad.corroboration import (
|
|
33
|
+
CappedCorroborationPolicy,
|
|
34
|
+
SharedLineageDetector,
|
|
35
|
+
evaluate_corroboration,
|
|
36
|
+
)
|
|
37
|
+
from isnad.grading import RefinedWeakestLink, grade_chain
|
|
38
|
+
from isnad.matn import DeterministicRuleCritic, LLMCritic
|
|
39
|
+
from isnad.matrix import decide, describe_action
|
|
40
|
+
from isnad.registry import Registry, ThresholdTransitionPolicy
|
|
41
|
+
from isnad.types import (
|
|
42
|
+
Action,
|
|
43
|
+
AdalahGrade,
|
|
44
|
+
ChainGrade,
|
|
45
|
+
ChainStatus,
|
|
46
|
+
ContentVerdict,
|
|
47
|
+
CorrelationDetector,
|
|
48
|
+
CorroborationPolicy,
|
|
49
|
+
DabtGrade,
|
|
50
|
+
EvidenceAction,
|
|
51
|
+
EvidenceType,
|
|
52
|
+
GradingStrategy,
|
|
53
|
+
NarratorGrade,
|
|
54
|
+
NarratorType,
|
|
55
|
+
TransformType,
|
|
56
|
+
TransitionPolicy,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
__all__ = [
|
|
60
|
+
# chain
|
|
61
|
+
"Chain",
|
|
62
|
+
"ChainLinkSpec",
|
|
63
|
+
"make_claim_id",
|
|
64
|
+
"normalize_claim_text",
|
|
65
|
+
# corroboration
|
|
66
|
+
"CappedCorroborationPolicy",
|
|
67
|
+
"SharedLineageDetector",
|
|
68
|
+
"evaluate_corroboration",
|
|
69
|
+
# grading
|
|
70
|
+
"RefinedWeakestLink",
|
|
71
|
+
"grade_chain",
|
|
72
|
+
# matn
|
|
73
|
+
"DeterministicRuleCritic",
|
|
74
|
+
"LLMCritic",
|
|
75
|
+
# matrix
|
|
76
|
+
"decide",
|
|
77
|
+
"describe_action",
|
|
78
|
+
# registry
|
|
79
|
+
"Registry",
|
|
80
|
+
"ThresholdTransitionPolicy",
|
|
81
|
+
# types
|
|
82
|
+
"Action",
|
|
83
|
+
"AdalahGrade",
|
|
84
|
+
"ChainGrade",
|
|
85
|
+
"ChainStatus",
|
|
86
|
+
"ContentVerdict",
|
|
87
|
+
"CorroborationPolicy",
|
|
88
|
+
"CorrelationDetector",
|
|
89
|
+
"DabtGrade",
|
|
90
|
+
"EvidenceAction",
|
|
91
|
+
"EvidenceType",
|
|
92
|
+
"GradingStrategy",
|
|
93
|
+
"NarratorGrade",
|
|
94
|
+
"NarratorType",
|
|
95
|
+
"TransformType",
|
|
96
|
+
"TransitionPolicy",
|
|
97
|
+
]
|