@soulguard/core 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 (94) hide show
  1. package/README.md +127 -0
  2. package/dist/cli.js +8838 -0
  3. package/dist/index.js +6555 -0
  4. package/package.json +35 -0
  5. package/src/approve.test.ts +386 -0
  6. package/src/approve.ts +352 -0
  7. package/src/cli/approve-command.ts +107 -0
  8. package/src/cli/diff-command.test.ts +61 -0
  9. package/src/cli/diff-command.ts +81 -0
  10. package/src/cli/init-command.ts +83 -0
  11. package/src/cli/reset-command.ts +36 -0
  12. package/src/cli/status-command.test.ts +90 -0
  13. package/src/cli/status-command.ts +78 -0
  14. package/src/cli/sync-command.test.ts +67 -0
  15. package/src/cli/sync-command.ts +105 -0
  16. package/src/cli.ts +224 -0
  17. package/src/console-live.ts +32 -0
  18. package/src/console-mock.ts +48 -0
  19. package/src/console.ts +12 -0
  20. package/src/constants.ts +21 -0
  21. package/src/diff.test.ts +189 -0
  22. package/src/diff.ts +212 -0
  23. package/src/git.test.ts +180 -0
  24. package/src/git.ts +131 -0
  25. package/src/glob.test.ts +74 -0
  26. package/src/glob.ts +84 -0
  27. package/src/index.ts +100 -0
  28. package/src/init.test.ts +234 -0
  29. package/src/init.ts +317 -0
  30. package/src/policy.test.ts +123 -0
  31. package/src/policy.ts +100 -0
  32. package/src/reset.test.ts +68 -0
  33. package/src/reset.ts +63 -0
  34. package/src/result.ts +14 -0
  35. package/src/schema.test.ts +27 -0
  36. package/src/schema.ts +22 -0
  37. package/src/self-protection.test.ts +139 -0
  38. package/src/self-protection.ts +63 -0
  39. package/src/status.test.ts +241 -0
  40. package/src/status.ts +114 -0
  41. package/src/sync.test.ts +172 -0
  42. package/src/sync.ts +101 -0
  43. package/src/system-ops-mock.ts +243 -0
  44. package/src/system-ops-node.test.ts +183 -0
  45. package/src/system-ops-node.ts +499 -0
  46. package/src/system-ops.ts +109 -0
  47. package/src/types.ts +91 -0
  48. package/src/vault-check.test.ts +41 -0
  49. package/src/vault-check.ts +24 -0
  50. package/test-e2e/Dockerfile +29 -0
  51. package/test-e2e/cases/approve-with-hash/expected.txt +16 -0
  52. package/test-e2e/cases/approve-with-hash/test.sh +23 -0
  53. package/test-e2e/cases/diff-no-changes/expected.txt +5 -0
  54. package/test-e2e/cases/diff-no-changes/test.sh +7 -0
  55. package/test-e2e/cases/diff-no-staging/expected.txt +1 -0
  56. package/test-e2e/cases/diff-no-staging/test.sh +6 -0
  57. package/test-e2e/cases/diff-shows-changes/expected.txt +13 -0
  58. package/test-e2e/cases/diff-shows-changes/test.sh +12 -0
  59. package/test-e2e/cases/diff-vault-missing/expected.txt +6 -0
  60. package/test-e2e/cases/diff-vault-missing/test.sh +10 -0
  61. package/test-e2e/cases/glob-ledger-files/expected.txt +52 -0
  62. package/test-e2e/cases/glob-ledger-files/test.sh +28 -0
  63. package/test-e2e/cases/glob-vault-files/expected.txt +41 -0
  64. package/test-e2e/cases/glob-vault-files/test.sh +30 -0
  65. package/test-e2e/cases/init-blocked-by-agent/expected.txt +11 -0
  66. package/test-e2e/cases/init-blocked-by-agent/test.sh +15 -0
  67. package/test-e2e/cases/init-happy/expected.txt +18 -0
  68. package/test-e2e/cases/init-happy/test.sh +20 -0
  69. package/test-e2e/cases/init-idempotent/expected.txt +13 -0
  70. package/test-e2e/cases/init-idempotent/test.sh +14 -0
  71. package/test-e2e/cases/reset-staging/expected.txt +16 -0
  72. package/test-e2e/cases/reset-staging/test.sh +23 -0
  73. package/test-e2e/cases/self-protection-blocks-invalid/expected.txt +12 -0
  74. package/test-e2e/cases/self-protection-blocks-invalid/test.sh +25 -0
  75. package/test-e2e/cases/status-clean/expected.txt +9 -0
  76. package/test-e2e/cases/status-clean/test.sh +8 -0
  77. package/test-e2e/cases/status-drifted/expected.txt +9 -0
  78. package/test-e2e/cases/status-drifted/test.sh +11 -0
  79. package/test-e2e/cases/status-no-config/expected.txt +1 -0
  80. package/test-e2e/cases/status-no-config/test.sh +2 -0
  81. package/test-e2e/cases/sync-fix-drift/expected.txt +15 -0
  82. package/test-e2e/cases/sync-fix-drift/test.sh +14 -0
  83. package/test-e2e/cases/sync-no-sudo-clean/expected.txt +11 -0
  84. package/test-e2e/cases/sync-no-sudo-clean/test.sh +9 -0
  85. package/test-e2e/cases/sync-no-sudo-drift/expected.txt +7 -0
  86. package/test-e2e/cases/sync-no-sudo-drift/test.sh +10 -0
  87. package/test-e2e/cases/vault-remove-file/expected.txt +26 -0
  88. package/test-e2e/cases/vault-remove-file/test.sh +31 -0
  89. package/test-e2e/cases/vault-write-blocked/expected.txt +8 -0
  90. package/test-e2e/cases/vault-write-blocked/test.sh +14 -0
  91. package/test-e2e/run-tests.sh +76 -0
  92. package/test-integration/Dockerfile +17 -0
  93. package/test-integration/system-ops-node.integration.test.ts +170 -0
  94. package/tsconfig.json +8 -0
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @soulguard/core
2
+
3
+ Vault enforcement, ledger tracking, approval workflow, git integration, and CLI for soulguard.
4
+
5
+ ## What Core Does
6
+
7
+ - Enforces vault file permissions (444, soulguardian-owned)
8
+ - Tracks ledger file ownership/permissions
9
+ - Manages implicit proposals (staging → diff → approve)
10
+ - Handles vault file deletion through staging
11
+ - Resolves glob patterns in vault/ledger config
12
+ - Auto-commits vault and ledger changes to git
13
+ - Self-protection (soulguard.json cannot be deleted or corrupted)
14
+
15
+ ## Library API
16
+
17
+ Core exports functions for programmatic use (e.g. by `@soulguard/openclaw` or daemon/cove integration):
18
+
19
+ ```typescript
20
+ import {
21
+ init,
22
+ status,
23
+ sync,
24
+ diff,
25
+ approve,
26
+ reset,
27
+ commitLedgerFiles,
28
+ gitCommit,
29
+ isGitEnabled,
30
+ isVaultedFile,
31
+ isGlob,
32
+ resolvePatterns,
33
+ } from "@soulguard/core";
34
+ ```
35
+
36
+ ### Key Functions
37
+
38
+ **`init(options)`** — One-time workspace setup. Creates system user/group, sets file permissions, generates sudoers, initializes staging, commits to git.
39
+
40
+ **`status(options)`** — Returns vault and ledger file health (ok, drifted, missing, error).
41
+
42
+ **`sync(options)`** — Fixes ownership/permission drift on vault and ledger files.
43
+
44
+ **`diff(options)`** — Compares staging against vault. Returns per-file diffs and an approval hash.
45
+
46
+ **`approve(options)`** — Applies staged changes to vault files. Validates approval hash, handles deletions, auto-commits to git.
47
+
48
+ **`reset(options)`** — Resets staging copies to match current vault state.
49
+
50
+ **`commitLedgerFiles(ops, config)`** — Standalone git commit for ledger files. Exported for daemon/cove to call on their own schedule (not part of `sync`).
51
+
52
+ ### Types
53
+
54
+ ```typescript
55
+ // Status result per file
56
+ type FileStatus =
57
+ | { status: "ok"; file: TrackedFile }
58
+ | { status: "drifted"; file: TrackedFile; issues: DriftIssue[] }
59
+ | { status: "missing"; path: string }
60
+ | { status: "error"; path: string; error: IOError };
61
+
62
+ // Diff result per file
63
+ type FileDiff =
64
+ | { status: "modified"; path: string; diff: string; protectedHash: string; stagedHash: string }
65
+ | { status: "unchanged"; path: string }
66
+ | { status: "missing_staging"; path: string }
67
+ | { status: "deleted"; path: string; protectedHash: string };
68
+
69
+ // Git commit result (discriminated union)
70
+ type GitCommitResult =
71
+ | { committed: true; message: string; files: string[] }
72
+ | { committed: false; reason: "git_disabled" | "no_files" | "nothing_staged" | "dirty_staging" };
73
+ ```
74
+
75
+ ## CLI
76
+
77
+ The CLI is the primary user interface. All commands take a workspace path as the first argument.
78
+
79
+ ```bash
80
+ # Setup
81
+ sudo soulguard init /workspace --agent-user agent
82
+
83
+ # Check health
84
+ soulguard status /workspace
85
+ sudo soulguard sync /workspace
86
+
87
+ # Review and approve changes
88
+ soulguard diff /workspace
89
+ sudo soulguard approve /workspace --hash <hash>
90
+
91
+ # Reset staging
92
+ sudo soulguard reset /workspace
93
+ ```
94
+
95
+ See [DESIGN.md](../../DESIGN.md#cli-reference) for the full command reference.
96
+
97
+ ## System Operations
98
+
99
+ Core uses a `SystemOperations` interface for all filesystem and OS interactions. This enables:
100
+
101
+ - **`NodeSystemOps`** — real filesystem operations for production
102
+ - **`MockSystemOps`** — in-memory mock for unit testing
103
+
104
+ The mock tracks all operations as a recorded log, supports glob matching, and allows configuring failures for error path testing.
105
+
106
+ ## Testing
107
+
108
+ ```bash
109
+ # Unit tests (135 tests)
110
+ bun test packages/core/src/
111
+
112
+ # E2e tests (20 tests, requires Docker)
113
+ bash packages/core/test-e2e/run-tests.sh
114
+
115
+ # Update e2e snapshots
116
+ bash packages/core/test-e2e/run-tests.sh --update
117
+ ```
118
+
119
+ E2e tests run each case in an isolated Docker container with real OS users, file permissions, and sudo — testing the actual security boundary.
120
+
121
+ ## Dependencies
122
+
123
+ - TypeScript, Node.js 22+ (for `fs.glob`)
124
+ - `commander` — CLI framework
125
+ - `diff` — unified diff generation
126
+
127
+ No daemon, no HTTP server, no file watching. Core is a library + CLI.