forked from rapmd73/AxiomEngine
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathledger.py
More file actions
173 lines (153 loc) · 6.14 KB
/
ledger.py
File metadata and controls
173 lines (153 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Axiom - ledger.py
# Copyright (C) 2025 The Axiom Contributors
# This program is licensed under the Peer Production License (PPL).
# See the LICENSE file for full details.
# --- UNIFIED V2 VERSION WITH ALL REQUIRED FUNCTIONS ---
import sqlite3
from datetime import datetime
import re
DB_NAME = "axiom_ledger.db"
def initialize_database():
"""
Ensures the database file and ALL required tables ('facts', 'fact_relationships') exist.
"""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
print("[Ledger] Initializing and verifying database schema...")
# --- Table 1: The 'facts' table ---
cursor.execute("""
CREATE TABLE IF NOT EXISTS facts (
fact_id TEXT PRIMARY KEY,
fact_content TEXT NOT NULL,
source_url TEXT NOT NULL,
ingest_timestamp_utc TEXT NOT NULL,
trust_score INTEGER NOT NULL DEFAULT 1,
status TEXT NOT NULL DEFAULT 'uncorroborated',
corroborating_sources TEXT,
contradicts_fact_id TEXT
)
""")
# --- Table 2: The 'fact_relationships' table for the Synthesizer ---
cursor.execute("""
CREATE TABLE IF NOT EXISTS fact_relationships (
relationship_id INTEGER PRIMARY KEY AUTOINCREMENT,
fact_id_1 TEXT NOT NULL,
fact_id_2 TEXT NOT NULL,
relationship_score REAL NOT NULL,
FOREIGN KEY (fact_id_1) REFERENCES facts (fact_id),
FOREIGN KEY (fact_id_2) REFERENCES facts (fact_id),
UNIQUE (fact_id_1, fact_id_2)
)
""")
conn.commit()
conn.close()
print("[Ledger] Database schema is up-to-date.")
def get_all_facts_for_analysis():
"""Retrieves all facts for the Crucible and Synthesizer."""
conn = sqlite3.connect(DB_NAME)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM facts")
all_facts = [dict(row) for row in cursor.fetchall()]
conn.close()
return all_facts
def find_similar_fact_from_different_domain(fact_content, source_domain, all_facts):
"""Searches for a similar fact from a different source domain."""
conn = sqlite3.connect(DB_NAME)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM facts")
all_facts = cursor.fetchall()
for fact in all_facts:
try:
existing_domain = re.search(r'https?://(?:www\.)?([^/]+)', fact['source_url']).group(1)
if source_domain.lower() == existing_domain.lower():
continue
except AttributeError:
continue
if fact_content[:50] == fact['fact_content'][:50]:
conn.close()
return dict(fact)
conn.close()
return None
def update_fact_corroboration(fact_id, new_source_url):
"""Increments a fact's trust score and updates its status."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("SELECT trust_score, corroborating_sources FROM facts WHERE fact_id = ?", (fact_id,))
result = cursor.fetchone()
if not result:
conn.close()
return
current_score, sources_text = result
new_score = current_score + 1
if sources_text:
new_sources = sources_text + "," + new_source_url
else:
new_sources = new_source_url
cursor.execute("""
UPDATE facts
SET trust_score = ?, status = 'trusted', corroborating_sources = ?
WHERE fact_id = ?
""", (new_score, new_sources, fact_id))
conn.commit()
conn.close()
print(f" [Ledger] SUCCESS: Corroborated existing fact. New trust score: {new_score}")
def insert_uncorroborated_fact(fact_id, fact_content, source_url):
"""Inserts a fact for the first time."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
timestamp = datetime.utcnow().isoformat()
try:
cursor.execute("""
INSERT INTO facts (fact_id, fact_content, source_url, ingest_timestamp_utc, trust_score, status)
VALUES (?, ?, ?, ?, 1, 'uncorroborated')
""", (fact_id, fact_content, source_url, timestamp))
conn.commit()
return { "fact_id": fact_id, "fact_content": fact_content, "source_url": source_url }
except sqlite3.IntegrityError:
return None
finally:
conn.close()
def insert_relationship(fact_id_1, fact_id_2, score):
"""Inserts a relationship between two facts into the knowledge graph."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
try:
if fact_id_1 > fact_id_2:
fact_id_1, fact_id_2 = fact_id_2, fact_id_1
cursor.execute("""
INSERT INTO fact_relationships (fact_id_1, fact_id_2, relationship_score)
VALUES (?, ?, ?)
""", (fact_id_1, fact_id_2, score))
conn.commit()
except sqlite3.IntegrityError:
pass
finally:
conn.close()
# --- THIS IS THE MISSING FUNCTION THAT IS NOW ADDED BACK ---
def mark_facts_as_disputed(original_fact_id, new_fact_id, new_fact_content, new_source_url):
"""
Marks two facts as disputed and links them together.
"""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
timestamp = datetime.utcnow().isoformat()
try:
# Insert the new fact, marking it as disputed and linking it to the original.
cursor.execute("""
INSERT INTO facts (fact_id, fact_content, source_url, ingest_timestamp_utc, trust_score, status, contradicts_fact_id)
VALUES (?, ?, ?, ?, 1, 'disputed', ?)
""", (new_fact_id, new_fact_content, new_source_url, timestamp, original_fact_id))
# Update the original fact, marking it as disputed and linking it to the new one.
cursor.execute("""
UPDATE facts
SET status = 'disputed', contradicts_fact_id = ?
WHERE fact_id = ?
""", (new_fact_id, original_fact_id))
conn.commit()
print(f" [Ledger] CONTRADICTION DETECTED: Facts {original_fact_id[:6]}... and {new_fact_id[:6]}... have been marked as disputed.")
except Exception as e:
print(f" [Ledger] ERROR: Could not mark facts as disputed. {e}")
finally:
conn.close()