@smilintux/skcapstone 0.1.0

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 (50) hide show
  1. package/.cursorrules +33 -0
  2. package/.github/workflows/ci.yml +23 -0
  3. package/.github/workflows/publish.yml +52 -0
  4. package/AGENTS.md +74 -0
  5. package/CLAUDE.md +56 -0
  6. package/LICENSE +674 -0
  7. package/README.md +242 -0
  8. package/SKILL.md +36 -0
  9. package/bin/cli.js +18 -0
  10. package/docs/ARCHITECTURE.md +510 -0
  11. package/docs/SECURITY_DESIGN.md +315 -0
  12. package/docs/SOVEREIGN_SINGULARITY.md +371 -0
  13. package/docs/TOKEN_SYSTEM.md +201 -0
  14. package/index.d.ts +9 -0
  15. package/index.js +32 -0
  16. package/package.json +32 -0
  17. package/pyproject.toml +84 -0
  18. package/src/skcapstone/__init__.py +13 -0
  19. package/src/skcapstone/cli.py +1441 -0
  20. package/src/skcapstone/connectors/__init__.py +6 -0
  21. package/src/skcapstone/coordination.py +590 -0
  22. package/src/skcapstone/discovery.py +275 -0
  23. package/src/skcapstone/memory_engine.py +457 -0
  24. package/src/skcapstone/models.py +223 -0
  25. package/src/skcapstone/pillars/__init__.py +8 -0
  26. package/src/skcapstone/pillars/identity.py +91 -0
  27. package/src/skcapstone/pillars/memory.py +61 -0
  28. package/src/skcapstone/pillars/security.py +83 -0
  29. package/src/skcapstone/pillars/sync.py +486 -0
  30. package/src/skcapstone/pillars/trust.py +335 -0
  31. package/src/skcapstone/runtime.py +190 -0
  32. package/src/skcapstone/skills/__init__.py +1 -0
  33. package/src/skcapstone/skills/syncthing_setup.py +297 -0
  34. package/src/skcapstone/sync/__init__.py +14 -0
  35. package/src/skcapstone/sync/backends.py +330 -0
  36. package/src/skcapstone/sync/engine.py +301 -0
  37. package/src/skcapstone/sync/models.py +97 -0
  38. package/src/skcapstone/sync/vault.py +284 -0
  39. package/src/skcapstone/tokens.py +439 -0
  40. package/tests/__init__.py +0 -0
  41. package/tests/conftest.py +42 -0
  42. package/tests/test_coordination.py +299 -0
  43. package/tests/test_discovery.py +57 -0
  44. package/tests/test_memory_engine.py +391 -0
  45. package/tests/test_models.py +63 -0
  46. package/tests/test_pillars.py +87 -0
  47. package/tests/test_runtime.py +60 -0
  48. package/tests/test_sync.py +507 -0
  49. package/tests/test_syncthing_setup.py +76 -0
  50. package/tests/test_tokens.py +265 -0
@@ -0,0 +1,91 @@
1
+ """
2
+ Identity pillar — CapAuth integration.
3
+
4
+ PGP-based sovereign identity. The agent IS its key.
5
+ No corporate SSO. No OAuth dance. Cryptographic proof of self.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import subprocess
12
+ from datetime import datetime, timezone
13
+ from pathlib import Path
14
+ from typing import Optional
15
+
16
+ from ..models import IdentityState, PillarStatus
17
+
18
+
19
+ def generate_identity(
20
+ home: Path,
21
+ name: str,
22
+ email: Optional[str] = None,
23
+ ) -> IdentityState:
24
+ """Generate a new sovereign identity for the agent.
25
+
26
+ Tries CapAuth first (full PGP key generation).
27
+ Falls back to recording identity metadata without key material.
28
+
29
+ Args:
30
+ home: Agent home directory (~/.skcapstone).
31
+ name: Agent display name.
32
+ email: Optional email for the identity.
33
+
34
+ Returns:
35
+ IdentityState with the new identity.
36
+ """
37
+ identity_dir = home / "identity"
38
+ identity_dir.mkdir(parents=True, exist_ok=True)
39
+
40
+ state = IdentityState(
41
+ name=name,
42
+ email=email or f"{name.lower().replace(' ', '-')}@skcapstone.local",
43
+ created_at=datetime.now(timezone.utc),
44
+ status=PillarStatus.DEGRADED,
45
+ )
46
+
47
+ try:
48
+ from capauth.keys import generate_keypair # type: ignore[import-untyped]
49
+
50
+ pub_key, fingerprint = generate_keypair(
51
+ name=name,
52
+ email=state.email,
53
+ output_dir=str(identity_dir),
54
+ )
55
+ state.fingerprint = fingerprint
56
+ state.key_path = identity_dir / "agent.pub"
57
+ state.status = PillarStatus.ACTIVE
58
+ except (ImportError, Exception):
59
+ # Reason: CapAuth not installed or key generation failed —
60
+ # record identity metadata anyway so agent has a name
61
+ state.fingerprint = _generate_placeholder_fingerprint(name)
62
+ state.status = PillarStatus.DEGRADED
63
+
64
+ identity_manifest = {
65
+ "name": state.name,
66
+ "email": state.email,
67
+ "fingerprint": state.fingerprint,
68
+ "created_at": state.created_at.isoformat() if state.created_at else None,
69
+ "capauth_managed": state.status == PillarStatus.ACTIVE,
70
+ }
71
+ (identity_dir / "identity.json").write_text(json.dumps(identity_manifest, indent=2))
72
+
73
+ return state
74
+
75
+
76
+ def _generate_placeholder_fingerprint(name: str) -> str:
77
+ """Generate a deterministic placeholder fingerprint from the agent name.
78
+
79
+ Not cryptographic — just a consistent identifier until CapAuth
80
+ is installed and proper PGP keys are generated.
81
+
82
+ Args:
83
+ name: Agent display name.
84
+
85
+ Returns:
86
+ A hex string resembling a fingerprint.
87
+ """
88
+ import hashlib
89
+
90
+ digest = hashlib.sha256(f"skcapstone:{name}".encode()).hexdigest()
91
+ return digest[:40].upper()
@@ -0,0 +1,61 @@
1
+ """
2
+ Memory pillar — sovereign memory initialization.
3
+
4
+ Persistent context across platforms and sessions.
5
+ The agent remembers. Always. Everywhere.
6
+
7
+ The built-in memory engine (memory_engine.py) provides full
8
+ store/search/recall/list/gc capabilities. The optional external
9
+ `skmemory` package adds legacy compatibility but is NOT required.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from pathlib import Path
15
+ from typing import Optional
16
+
17
+ from ..models import MemoryLayer, MemoryState, PillarStatus
18
+
19
+
20
+ def initialize_memory(home: Path, memory_home: Optional[Path] = None) -> MemoryState:
21
+ """Initialize memory for the agent.
22
+
23
+ Creates the memory directory structure with layer subdirs.
24
+ The built-in memory engine handles all operations; no
25
+ external package required.
26
+
27
+ Args:
28
+ home: Agent home directory (~/.skcapstone).
29
+ memory_home: Unused, kept for backward compatibility.
30
+
31
+ Returns:
32
+ MemoryState after initialization.
33
+ """
34
+ memory_dir = home / "memory"
35
+ memory_dir.mkdir(parents=True, exist_ok=True)
36
+
37
+ for layer in MemoryLayer:
38
+ (memory_dir / layer.value).mkdir(parents=True, exist_ok=True)
39
+
40
+ state = MemoryState(store_path=memory_dir, status=PillarStatus.ACTIVE)
41
+ return state
42
+
43
+
44
+ def get_memory_stats(home: Path) -> dict:
45
+ """Get current memory statistics from the built-in engine.
46
+
47
+ Args:
48
+ home: Agent home directory (~/.skcapstone).
49
+
50
+ Returns:
51
+ Dict with memory layer counts.
52
+ """
53
+ from ..memory_engine import get_stats
54
+
55
+ stats = get_stats(home)
56
+ return {
57
+ "short_term": stats.short_term,
58
+ "mid_term": stats.mid_term,
59
+ "long_term": stats.long_term,
60
+ "total": stats.total_memories,
61
+ }
@@ -0,0 +1,83 @@
1
+ """
2
+ Security pillar — SKSecurity integration.
3
+
4
+ Audit everything. Detect threats. Protect the sovereign.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from datetime import datetime, timezone
11
+ from pathlib import Path
12
+
13
+ from ..models import PillarStatus, SecurityState
14
+
15
+
16
+ def initialize_security(home: Path) -> SecurityState:
17
+ """Initialize security layer for the agent.
18
+
19
+ Creates audit log structure and baseline security config.
20
+
21
+ Args:
22
+ home: Agent home directory (~/.skcapstone).
23
+
24
+ Returns:
25
+ SecurityState after initialization.
26
+ """
27
+ security_dir = home / "security"
28
+ security_dir.mkdir(parents=True, exist_ok=True)
29
+
30
+ state = SecurityState()
31
+
32
+ try:
33
+ import sksecurity # type: ignore[import-untyped]
34
+
35
+ state.status = PillarStatus.DEGRADED
36
+ except ImportError:
37
+ security_config = {
38
+ "note": "Install sksecurity (pip install sksecurity) for full security",
39
+ "audit_enabled": True,
40
+ }
41
+ (security_dir / "security.json").write_text(json.dumps(security_config, indent=2))
42
+ state.status = PillarStatus.DEGRADED
43
+ _init_audit_log(security_dir)
44
+ return state
45
+
46
+ _init_audit_log(security_dir)
47
+
48
+ baseline = {
49
+ "threats_detected": 0,
50
+ "last_scan": None,
51
+ "audit_enabled": True,
52
+ "initialized_at": datetime.now(timezone.utc).isoformat(),
53
+ }
54
+ (security_dir / "security.json").write_text(json.dumps(baseline, indent=2))
55
+
56
+ return state
57
+
58
+
59
+ def _init_audit_log(security_dir: Path) -> None:
60
+ """Create the audit log file with a header entry."""
61
+ audit_log = security_dir / "audit.log"
62
+ if not audit_log.exists():
63
+ timestamp = datetime.now(timezone.utc).isoformat()
64
+ audit_log.write_text(f"[{timestamp}] INIT — SKCapstone security audit log created\n")
65
+
66
+
67
+ def audit_event(home: Path, event_type: str, detail: str) -> None:
68
+ """Append an event to the audit log.
69
+
70
+ Args:
71
+ home: Agent home directory.
72
+ event_type: Event category (INIT, AUTH, MEMORY, TRUST, etc.).
73
+ detail: Human-readable event description.
74
+ """
75
+ security_dir = home / "security"
76
+ security_dir.mkdir(parents=True, exist_ok=True)
77
+ audit_log = security_dir / "audit.log"
78
+
79
+ timestamp = datetime.now(timezone.utc).isoformat()
80
+ entry = f"[{timestamp}] {event_type} — {detail}\n"
81
+
82
+ with audit_log.open("a") as f:
83
+ f.write(entry)