ethernium-continuity-lite 2.1.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.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Ethernium (X: @Steveblackbeard)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: ethernium-continuity-lite
3
+ Version: 2.1.0
4
+ Summary: Continuity Legacy (Lite): A professional AI continuity framework for zero-friction context handoffs.
5
+ Author: SteveBlackbeard
6
+ Project-URL: Homepage, https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: typer[all]>=0.9.0
14
+ Requires-Dist: rich>=13.0.0
15
+ Dynamic: license-file
16
+
17
+ # Continuity Lite (v2.1.0) - Evolution DNA Guardian
18
+
19
+
20
+
21
+ [![Version](https://img.shields.io/badge/version-2.1.0-blue.svg)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
22
+
23
+ [![Requirement](https://img.shields.io/badge/hardware-minimalist-green.svg)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
24
+
25
+ [![Stars](https://img.shields.io/github/stars/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium?style=social)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
26
+
27
+
28
+
29
+ **Lite** is the fastest contextual guardian for Human-AI parity. Zero dependencies, instant execution.
30
+
31
+
32
+
33
+ ---
34
+
35
+
36
+
37
+ ## Installation (Quick)
38
+
39
+
40
+
41
+ ```bash
42
+
43
+ # Install the Lite edition from its folder
44
+
45
+ pip install -e .
46
+
47
+
48
+
49
+ # Setup the DNA Guardian Entry Point
50
+
51
+ continuity-lite --hook
52
+
53
+ ```
54
+
55
+
56
+
57
+ ---
58
+
59
+
60
+
61
+ ## Minimal Usage
62
+
63
+
64
+
65
+ ```bash
66
+
67
+ # Run the DNA validation cycle
68
+
69
+ continuity-lite
70
+
71
+ ```
72
+
73
+
74
+
75
+ ---
76
+
77
+
78
+
79
+ ## Hardware Profile
80
+
81
+ - **CPU**: Minimal (Any).
82
+
83
+ - **RAM**: < 100MB.
84
+
85
+ - **Python**: 3.7+ (No external dependencies).
86
+
87
+
88
+
89
+ ---
90
+
91
+ *Continuity: Protecting the logical lineage of your software.*
92
+
@@ -0,0 +1,38 @@
1
+ # Continuity Lite (v2.1.0) - Evolution DNA Guardian
2
+
3
+ [![Version](https://img.shields.io/badge/version-2.1.0-blue.svg)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
4
+ [![Requirement](https://img.shields.io/badge/hardware-minimalist-green.svg)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
5
+ [![Stars](https://img.shields.io/github/stars/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium?style=social)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
6
+
7
+ **Lite** is the fastest contextual guardian for Human-AI parity. Zero dependencies, instant execution.
8
+
9
+ ---
10
+
11
+ ## Installation (Quick)
12
+
13
+ ```bash
14
+ # Install the Lite edition from its folder
15
+ pip install -e .
16
+
17
+ # Setup the DNA Guardian Entry Point
18
+ continuity-lite --hook
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Minimal Usage
24
+
25
+ ```bash
26
+ # Run the DNA validation cycle
27
+ continuity-lite
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Hardware Profile
33
+ - **CPU**: Minimal (Any).
34
+ - **RAM**: < 100MB.
35
+ - **Python**: 3.7+ (No external dependencies).
36
+
37
+ ---
38
+ *Continuity: Protecting the logical lineage of your software.*
@@ -0,0 +1,247 @@
1
+ import logging
2
+ import hashlib
3
+ import os
4
+ import json
5
+ from pathlib import Path
6
+ from datetime import datetime
7
+ from typing import Optional
8
+ import sys
9
+
10
+ import typer
11
+ from rich.console import Console
12
+ from rich.panel import Panel
13
+ from rich.table import Table
14
+ from rich.progress import Progress, SpinnerColumn, TextColumn
15
+ from rich import print as rprint
16
+
17
+ # CONTINUITY LEGACY Lite (v2.1.0) - Evolution DNA Guardian
18
+ # -------------------------------------------------------------
19
+ # [!] Industrial Grade Refactor: Typer CLI, Rich UI, SHA-256 Signatures, Structured Logs.
20
+
21
+ app = typer.Typer(
22
+ help="🏛️ Continuity Legacy Lite: The professional AI continuity framework.",
23
+ add_completion=False,
24
+ no_args_is_help=True
25
+ )
26
+ console = Console()
27
+
28
+ def setup_logger(repo_root: Path):
29
+ log_dir = repo_root / ".continuity" / "logs"
30
+ log_dir.mkdir(parents=True, exist_ok=True)
31
+
32
+ log_file = log_dir / f"continuity_{datetime.now().strftime('%Y%m%d')}.jsonl"
33
+
34
+ # Custom JSON Formatter
35
+ class JsonFormatter(logging.Formatter):
36
+ def format(self, record):
37
+ log_record = {
38
+ "timestamp": datetime.utcnow().isoformat() + "Z",
39
+ "level": record.levelname,
40
+ "message": record.getMessage(),
41
+ "module": record.module
42
+ }
43
+ if hasattr(record, "dna_hash"):
44
+ log_record["dna_hash"] = record.dna_hash
45
+ return json.dumps(log_record)
46
+
47
+ logger = logging.getLogger("continuity")
48
+ logger.setLevel(logging.INFO)
49
+
50
+ if not logger.handlers:
51
+ fh = logging.FileHandler(log_file)
52
+ fh.setFormatter(JsonFormatter())
53
+ logger.addHandler(fh)
54
+ return logger
55
+
56
+ ASCII_ART = """
57
+ [bold cyan]
58
+ ______ ____ _ __ ______ ____ _ __ _ __ ____ ______ __ __
59
+ / ____// __ \\ / | / //_ __// _// | / // / / //_ __//_ __/ \\ \\/ /
60
+ / / / / / // |/ / / / / / / |/ // / / / / / / / \\ /
61
+ / /___ / /_/ // /| / / / _/ / / /| // /__/ / / / / / / /
62
+ \\____/ \\____//_/ |_/ /_/ /___//_/ |_/ \\____/ /_/ /_/ /_/
63
+
64
+ LEGACY [bold white]v2.1.0[/bold white] | [italic green]Industrial Evolution DNA Guardian[/italic green]
65
+ [/bold cyan]
66
+ """
67
+
68
+ def calculate_sha256(path: Path) -> str:
69
+ if not path.exists(): return ""
70
+ return hashlib.sha256(path.read_bytes()).hexdigest()
71
+
72
+ def sign_state(data: dict) -> str:
73
+ """Generates a SHA-256 signature for the state record.
74
+ Hardware binding has been removed to support Open Source collaboration across
75
+ different developer machines while maintaining semantic integrity.
76
+ """
77
+ serialized = json.dumps({k: v for k, v in data.items() if k != "signature"}, sort_keys=True)
78
+ return hashlib.sha256(serialized.encode("utf-8")).hexdigest()
79
+
80
+ def ensure_file(path: Path, template: str, description: str):
81
+ if not path.exists():
82
+ console.log(f"[yellow][?][/yellow] Missing Nucleotide: [bold]{description}[/bold]")
83
+ path.parent.mkdir(parents=True, exist_ok=True)
84
+ path.write_text(template, encoding="utf-8")
85
+ console.log(f" [green][✔][/green] Re-synthesized: [italic]{path.name}[/italic]")
86
+ return True
87
+ return False
88
+
89
+ def install_hooks(repo_root: Path):
90
+ hook_path = repo_root / ".git" / "hooks" / "pre-push"
91
+ if not (repo_root / ".git").exists():
92
+ console.log("[bold red][!][/bold red] ERROR: Not a git repository. Cannot install hooks.")
93
+ return
94
+
95
+ # Vector 1: Prevenir secuestro de $PATH inyectando ruta absoluta al binario
96
+ abs_python = sys.executable.replace("\\", "/")
97
+ abs_script = Path(__file__).resolve().as_posix()
98
+
99
+ # Vector 3: Mantener política Fail-Closed (|| exit 1)
100
+ hook_content = f"#!/bin/sh\n# Continuity Sentinel Guardian (Fail-Closed Security)\necho '[*] 🏛️ Ethernium: Guarding DNA Lineage...'\n\"{abs_python}\" \"{abs_script}\" check\nRESULT=$?\nif [ $RESULT -ne 0 ]; then\n echo '[!] PUSH REJECTED: DNA Drift Detected. Run continuity-lite check.'\n exit 1\nfi\nexit 0\n"
101
+ hook_path.parent.mkdir(parents=True, exist_ok=True)
102
+ hook_path.write_text(hook_content, encoding="utf-8")
103
+
104
+ if os.name != "nt": os.chmod(hook_path, 0o755)
105
+ console.log(f"[green][✔][/green] Push Hook Guardian (v2.1.0) installed and active.")
106
+
107
+
108
+ def build_merkle_root(hashes: list[str]) -> str:
109
+ """RFC 6962 compliant Merkle Tree with leaf/node prefix hardening."""
110
+ if not hashes: return "0" * 64
111
+ # Leaf nodes: H(0x00 || data)
112
+ current_level = [hashlib.sha256(b"\x00" + h.encode("utf-8")).hexdigest() for h in sorted(hashes)]
113
+ while len(current_level) > 1:
114
+ next_level = []
115
+ if len(current_level) % 2 != 0:
116
+ current_level.append(current_level[-1])
117
+ for i in range(0, len(current_level), 2):
118
+ # Internal nodes: H(0x01 || left || right)
119
+ combined = b"\x01" + (current_level[i] + current_level[i+1]).encode("utf-8")
120
+ next_level.append(hashlib.sha256(combined).hexdigest())
121
+ current_level = next_level
122
+ return current_level[0]
123
+
124
+ @app.command()
125
+ def init(
126
+ repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory."),
127
+ no_hook: bool = typer.Option(False, "--no-hook", help="Disable automatic Git-Hook installation.")
128
+ ):
129
+ """Initialize the Continuity memory core in the current project."""
130
+ console.print(ASCII_ART)
131
+ logger = setup_logger(repo_root)
132
+
133
+ root = repo_root.resolve()
134
+ logger.info("Initializing Continuity Core", extra={"repo_root": str(root)})
135
+
136
+ with Progress(
137
+ SpinnerColumn(),
138
+ TextColumn("[progress.description]{task.description}"),
139
+ transient=True,
140
+ ) as progress:
141
+ progress.add_task(description="Forging memory core...", total=None)
142
+
143
+ # Create core files
144
+ ensure_file(root / "PROJECT_CONTEXT.md", "# Project Context\n\n- Define your project core here.", "PROJECT_CONTEXT.md")
145
+ ensure_file(root / "LIVE_HANDOFF.md", "# Live Handoff\n\n- No handoff pending.", "LIVE_HANDOFF.md")
146
+
147
+ # Create and SIGN STATE.json
148
+ state_path = root / "STATE.json"
149
+ if not state_path.exists():
150
+ state_data = {"phase": "stable", "last_update": datetime.utcnow().isoformat()}
151
+ state_data["signature"] = sign_state(state_data)
152
+ state_path.write_text(json.dumps(state_data, indent=2), encoding="utf-8")
153
+ console.log(f" [green][✔][/green] Crystallized + Signed: [italic]STATE.json[/italic]")
154
+
155
+ if not no_hook:
156
+ install_hooks(root)
157
+
158
+ console.print(Panel("[bold green]Success:[/bold green] Continuity Core crystallized at root level. 🏛️💎🦾", title="Init Complete", expand=False))
159
+
160
+ @app.command()
161
+ def check(
162
+ repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory.")
163
+ ):
164
+ """Validate the DNA parity, Merkle Root integrity, and state signature."""
165
+ console.print(ASCII_ART)
166
+ root = repo_root.resolve()
167
+
168
+ md_files = []
169
+ for r, dirs, files in os.walk(root):
170
+ dirs[:] = [d for d in dirs if d not in [".git", "node_modules", ".continuity", "outputs"]]
171
+ for f in files:
172
+ if f.endswith(".md") and "PROJECT_DNA" not in f:
173
+ md_files.append(Path(r) / f)
174
+
175
+ nucleotides = [calculate_sha256(md) for md in sorted(md_files)]
176
+ merkle_root = build_merkle_root(nucleotides)
177
+
178
+ # Verify STATE.json signature integrity
179
+ state_path = root / "STATE.json"
180
+ if state_path.exists():
181
+ try:
182
+ state = json.loads(state_path.read_text(encoding="utf-8"))
183
+ # Verify cryptographic signature
184
+ if "signature" in state:
185
+ expected_sig = sign_state(state)
186
+ if state["signature"] != expected_sig:
187
+ console.print(f"[bold red][!] STATE TAMPERING DETECTED:[/bold red] Signature mismatch!")
188
+ console.print(f" Stored: [red]{state['signature'][:16]}...[/red]")
189
+ console.print(f" Expected: [cyan]{expected_sig[:16]}...[/cyan]")
190
+ raise typer.Exit(code=1)
191
+ console.print(f"[green][✔][/green] State signature verified.")
192
+
193
+ # Update Merkle Root in STATE.json
194
+ state["merkle_root"] = merkle_root
195
+ state["last_check"] = datetime.utcnow().isoformat()
196
+ state["signature"] = sign_state(state)
197
+ state_path.write_text(json.dumps(state, indent=2), encoding="utf-8")
198
+ except json.JSONDecodeError:
199
+ console.print("[red][!][/red] Error: Invalid STATE.json nucleotide.")
200
+
201
+ console.print(Panel(f"[bold green]Parity Confirmed:[/bold green] Merkle Root `{merkle_root[:16]}...`", title="DNA Guardian", expand=False))
202
+
203
+ @app.command()
204
+ def status(
205
+ repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory.")
206
+ ):
207
+ """View the current status of the logical lineage."""
208
+ root = repo_root.resolve()
209
+ state_path = root / "STATE.json"
210
+
211
+ if not state_path.exists():
212
+ console.print("[yellow]Continuity not initialized here. Use `init` first.[/yellow]")
213
+ return
214
+
215
+ state = json.loads(state_path.read_text(encoding="utf-8"))
216
+
217
+ table = Table(title="Lineage Status 🏛️", show_header=True, header_style="bold magenta")
218
+ table.add_column("Property", style="dim")
219
+ table.add_column("Value")
220
+
221
+ for k, v in state.items():
222
+ table.add_row(k, str(v))
223
+
224
+ console.print(table)
225
+
226
+ @app.command()
227
+ def log(
228
+ intent: str = typer.Argument(..., help="Detailed session intent capture."),
229
+ repo_root: Path = typer.Option(".", "--repo-root", help="Project root directory.")
230
+ ):
231
+ """Capture session intent into the permanent timeline."""
232
+ root = repo_root.resolve()
233
+ log_path = root / "SESSION_LOG.md"
234
+
235
+ if not log_path.exists():
236
+ log_path.write_text("# Continuity Session Log\n\n", encoding="utf-8")
237
+
238
+ with open(log_path, "a", encoding="utf-8") as f:
239
+ f.write(f"- [{datetime.utcnow().isoformat()}Z] {intent}\n")
240
+
241
+ console.log(f"[green][✔][/green] Intent captured in SESSION_LOG.md")
242
+
243
+ def main():
244
+ app()
245
+
246
+ if __name__ == "__main__":
247
+ main()
@@ -0,0 +1,79 @@
1
+ from __future__ import annotations
2
+ import argparse
3
+ import hashlib
4
+ import json
5
+ import os
6
+ import sys
7
+ from pathlib import Path
8
+ from datetime import datetime
9
+
10
+ # CONTINUITY LEGACY: Active Universal Translation Sync
11
+ # ----------------------------------------------------
12
+ # This script manages multilingual documentation across the 4 levels:
13
+ # Root, Pro, Lite, and Omega. It detects drift and can auto-generate READMEs.
14
+
15
+ LANG_CODES = ["es", "ja", "ru", "zh", "fr", "it", "de", "pt", "en"]
16
+
17
+ def calculate_md5(path: Path) -> str:
18
+ if not path.exists(): return ""
19
+ return hashlib.md5(path.read_bytes()).hexdigest()
20
+
21
+ def get_edition_name(root: Path) -> str:
22
+ # Detect which edition we are in
23
+ if (root / "CONTINUITY LEGACY Pro").exists(): return "Root Portal"
24
+ if "Pro" in root.name: return "Pro Edition"
25
+ if "Lite" in root.name: return "Lite Edition"
26
+ if "Omega" in root.name: return "Omega Edition"
27
+ return "Universal Core"
28
+
29
+ def generate_localized_readme(lang, edition_name, source_content):
30
+ # Professional localized templates
31
+ templates = {
32
+ "es": f"# CONTINUITY LEGACY: {edition_name}\n\nVersión localizada del framework de continuidad técnica.",
33
+ "ja": f"# CONTINUITY LEGACY: {edition_name}\n\nテクニカル・コンティニュイティ・フレームワークのローカライズ版。",
34
+ "ru": f"# CONTINUITY LEGACY: {edition_name}\n\nЛокализованная версия фреймворка технической непрерывности.",
35
+ "zh": f"# CONTINUITY LEGACY: {edition_name}\n\n技术连续性框架的本地化版本。",
36
+ }
37
+
38
+ # Generic fallback
39
+ base = templates.get(lang, f"# CONTINUITY LEGACY: {edition_name}\n\nLocalized version of the technical continuity framework.")
40
+
41
+ # Add strategic metadata footer
42
+ footer = f"\n\n---\n*CONTINUITY LEGACY: Global Infrastructure - Generated {datetime.utcnow().isoformat()}Z*"
43
+ return base + footer
44
+
45
+ def sync_all(repo_root: Path, auto_gen: bool):
46
+ edition = get_edition_name(repo_root)
47
+ source_path = repo_root / "README.md"
48
+
49
+ if not source_path.exists():
50
+ print(f"[!] ERROR: Source README.md not found in {repo_root}")
51
+ return
52
+
53
+ print(f"[*] SYNC: Analyzing {edition} in {repo_root}...")
54
+ source_hash = calculate_md5(source_path)
55
+
56
+ lang_dir = repo_root / "OTHER_LANGUAGES"
57
+ lang_dir.mkdir(parents=True, exist_ok=True)
58
+
59
+ for lang in LANG_CODES:
60
+ target_path = lang_dir / f"README_{lang}.md"
61
+
62
+ if auto_gen:
63
+ print(f" -> Updating {lang} README...")
64
+ content = generate_localized_readme(lang, edition, source_path.read_text(encoding="utf-8"))
65
+ target_path.write_text(content, encoding="utf-8")
66
+
67
+ print(f"[✔] SYNC: {edition} is now globally synchronized.")
68
+
69
+ def main() -> None:
70
+ parser = argparse.ArgumentParser(description="Active Universal Translation Sync.")
71
+ parser.add_argument("--repo-root", default=".")
72
+ parser.add_argument("--auto-generate", action="store_true", help="Automatically generate/update localized files.")
73
+ args = parser.parse_args()
74
+
75
+ root = Path(args.repo_root).resolve()
76
+ sync_all(root, args.auto_generate)
77
+
78
+ if __name__ == "__main__":
79
+ main()
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: ethernium-continuity-lite
3
+ Version: 2.1.0
4
+ Summary: Continuity Legacy (Lite): A professional AI continuity framework for zero-friction context handoffs.
5
+ Author: SteveBlackbeard
6
+ Project-URL: Homepage, https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: typer[all]>=0.9.0
14
+ Requires-Dist: rich>=13.0.0
15
+ Dynamic: license-file
16
+
17
+ # Continuity Lite (v2.1.0) - Evolution DNA Guardian
18
+
19
+
20
+
21
+ [![Version](https://img.shields.io/badge/version-2.1.0-blue.svg)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
22
+
23
+ [![Requirement](https://img.shields.io/badge/hardware-minimalist-green.svg)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
24
+
25
+ [![Stars](https://img.shields.io/github/stars/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium?style=social)](https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium)
26
+
27
+
28
+
29
+ **Lite** is the fastest contextual guardian for Human-AI parity. Zero dependencies, instant execution.
30
+
31
+
32
+
33
+ ---
34
+
35
+
36
+
37
+ ## Installation (Quick)
38
+
39
+
40
+
41
+ ```bash
42
+
43
+ # Install the Lite edition from its folder
44
+
45
+ pip install -e .
46
+
47
+
48
+
49
+ # Setup the DNA Guardian Entry Point
50
+
51
+ continuity-lite --hook
52
+
53
+ ```
54
+
55
+
56
+
57
+ ---
58
+
59
+
60
+
61
+ ## Minimal Usage
62
+
63
+
64
+
65
+ ```bash
66
+
67
+ # Run the DNA validation cycle
68
+
69
+ continuity-lite
70
+
71
+ ```
72
+
73
+
74
+
75
+ ---
76
+
77
+
78
+
79
+ ## Hardware Profile
80
+
81
+ - **CPU**: Minimal (Any).
82
+
83
+ - **RAM**: < 100MB.
84
+
85
+ - **Python**: 3.7+ (No external dependencies).
86
+
87
+
88
+
89
+ ---
90
+
91
+ *Continuity: Protecting the logical lineage of your software.*
92
+
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ continuity_lite/continuity_legacy/run_continuity_lite.py
5
+ continuity_lite/continuity_legacy/sync_translations.py
6
+ ethernium_continuity_lite.egg-info/PKG-INFO
7
+ ethernium_continuity_lite.egg-info/SOURCES.txt
8
+ ethernium_continuity_lite.egg-info/dependency_links.txt
9
+ ethernium_continuity_lite.egg-info/entry_points.txt
10
+ ethernium_continuity_lite.egg-info/requires.txt
11
+ ethernium_continuity_lite.egg-info/top_level.txt
12
+ tests/test_lite_logic.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ continuity-lite = continuity_lite.continuity_legacy.run_continuity_lite:main
@@ -0,0 +1,2 @@
1
+ typer[all]>=0.9.0
2
+ rich>=13.0.0
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ethernium-continuity-lite"
7
+ version = "2.1.0"
8
+ authors = [
9
+ { name = "SteveBlackbeard" },
10
+ ]
11
+ description = "Continuity Legacy (Lite): A professional AI continuity framework for zero-friction context handoffs."
12
+ readme = "README.md"
13
+ requires-python = ">=3.8"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "typer[all]>=0.9.0",
21
+ "rich>=13.0.0",
22
+ ]
23
+
24
+ [project.urls]
25
+ "Homepage" = "https://github.com/SteveBlackbeard/CONTINUITY-LEGACY-by-Ethernium"
26
+
27
+ [project.scripts]
28
+ continuity-lite = "continuity_lite.continuity_legacy.run_continuity_lite:main"
29
+
30
+ [tool.setuptools.packages.find]
31
+ where = ["."]
32
+ include = ["continuity_lite*"]
33
+
34
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,85 @@
1
+ import hashlib
2
+ import pytest
3
+ from pathlib import Path
4
+ import sys
5
+
6
+ # CONTINUITY LEGACY: Logic Audit Tests (v2.1.1 - RFC 6962 Hardened)
7
+ # ------------------------------------------------------------------
8
+
9
+ sys.path.append(str(Path(__file__).parent.parent / 'continuity_lite' / 'continuity_legacy'))
10
+
11
+ from run_continuity_lite import build_merkle_root, calculate_sha256, sign_state
12
+
13
+ # --- SHA-256 Tests ---
14
+
15
+ def test_calculate_sha256(tmp_path):
16
+ test_file = tmp_path / "test.txt"
17
+ content = b"Ethernium Continuity Legacy"
18
+ test_file.write_bytes(content)
19
+ expected = hashlib.sha256(content).hexdigest()
20
+ assert calculate_sha256(test_file) == expected
21
+
22
+ def test_calculate_sha256_missing():
23
+ assert calculate_sha256(Path("non_existent_phantom.txt")) == ""
24
+
25
+ # --- Merkle Tree Tests (RFC 6962 compliant) ---
26
+
27
+ def test_build_merkle_root_empty():
28
+ assert build_merkle_root([]) == "0" * 64
29
+
30
+ def test_build_merkle_root_single():
31
+ h1 = "abc123"
32
+ # Single node: leaf hash = H(0x00 || "abc123")
33
+ expected = hashlib.sha256(b"\x00" + b"abc123").hexdigest()
34
+ assert build_merkle_root([h1]) == expected
35
+
36
+ def test_build_merkle_root_even():
37
+ # 2 nodes: sorted ["a", "b"]
38
+ # Leaf: L0 = H(0x00 || "a"), L1 = H(0x00 || "b")
39
+ # Root: H(0x01 || L0 || L1)
40
+ L0 = hashlib.sha256(b"\x00a").hexdigest()
41
+ L1 = hashlib.sha256(b"\x00b").hexdigest()
42
+ expected = hashlib.sha256(b"\x01" + (L0 + L1).encode("utf-8")).hexdigest()
43
+ assert build_merkle_root(["b", "a"]) == expected
44
+
45
+ def test_build_merkle_root_odd():
46
+ # 3 nodes sorted: ["a", "b", "c"]
47
+ # Leaves: L0=H(0x00||"a"), L1=H(0x00||"b"), L2=H(0x00||"c")
48
+ # Padded: L3 = L2 (duplicate)
49
+ # Level 1: N0=H(0x01||L0||L1), N1=H(0x01||L2||L3)
50
+ # Root: H(0x01||N0||N1)
51
+ L0 = hashlib.sha256(b"\x00a").hexdigest()
52
+ L1 = hashlib.sha256(b"\x00b").hexdigest()
53
+ L2 = hashlib.sha256(b"\x00c").hexdigest()
54
+ N0 = hashlib.sha256(b"\x01" + (L0 + L1).encode("utf-8")).hexdigest()
55
+ N1 = hashlib.sha256(b"\x01" + (L2 + L2).encode("utf-8")).hexdigest()
56
+ expected = hashlib.sha256(b"\x01" + (N0 + N1).encode("utf-8")).hexdigest()
57
+ assert build_merkle_root(["c", "b", "a"]) == expected
58
+
59
+ def test_merkle_deterministic_order():
60
+ """Tree must be order-independent (sorted internally)."""
61
+ assert build_merkle_root(["z", "a", "m"]) == build_merkle_root(["a", "m", "z"])
62
+
63
+ # --- State Signature Tests (Expert #1: Cybersecurity) ---
64
+
65
+ def test_sign_state_deterministic():
66
+ data = {"phase": "stable", "last_update": "2026-01-01T00:00:00"}
67
+ sig1 = sign_state(data)
68
+ sig2 = sign_state(data)
69
+ assert sig1 == sig2
70
+ assert len(sig1) == 64 # SHA-256 hex digest
71
+
72
+ def test_sign_state_excludes_signature_field():
73
+ data = {"phase": "stable", "signature": "old_sig"}
74
+ sig = sign_state(data)
75
+ # Changing the signature field should NOT change the hash
76
+ data2 = {"phase": "stable", "signature": "different_sig"}
77
+ assert sign_state(data2) == sig
78
+
79
+ def test_sign_state_detects_tampering():
80
+ data = {"phase": "stable", "last_update": "2026-01-01T00:00:00"}
81
+ sig = sign_state(data)
82
+ data["phase"] = "compromised"
83
+ assert sign_state(data) != sig
84
+
85
+