@unifyplane/logsdk 1.0.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 (48) hide show
  1. package/.github/copilot-instructions.md +48 -0
  2. package/README.md +8 -0
  3. package/contracts/specs/LogSDKFuntionalSpec.md +394 -0
  4. package/contracts/specs/fanout-semantics.v1.md +244 -0
  5. package/contracts/specs/sink-contract.v1.md +223 -0
  6. package/contracts/specs/step-record.v1.md +292 -0
  7. package/contracts/specs/validation-rules.v1.md +324 -0
  8. package/docs/LogSDK-Unified-Execution-Logging-Framework.md +93 -0
  9. package/docs/log_sdk_test_cases_traceability_plan.md +197 -0
  10. package/docs/log_sdk_test_coverage_report.md +198 -0
  11. package/docs/prompts/AuditorSDK.txt +214 -0
  12. package/package.json +29 -0
  13. package/src/core/clock.ts +25 -0
  14. package/src/core/context.ts +142 -0
  15. package/src/core/fanout.ts +38 -0
  16. package/src/core/ids.ts +35 -0
  17. package/src/core/message_constraints.ts +66 -0
  18. package/src/core/outcomes.ts +5 -0
  19. package/src/core/record_builder.ts +269 -0
  20. package/src/core/spool.ts +41 -0
  21. package/src/core/types.ts +56 -0
  22. package/src/crypto-shim.d.ts +9 -0
  23. package/src/fs-shim.d.ts +15 -0
  24. package/src/index.ts +107 -0
  25. package/src/node-test-shim.d.ts +1 -0
  26. package/src/perf_hooks-shim.d.ts +7 -0
  27. package/src/process-shim.d.ts +1 -0
  28. package/src/sinks/file_ndjson.ts +42 -0
  29. package/src/sinks/file_ndjson_sink.ts +45 -0
  30. package/src/sinks/sink_types.ts +15 -0
  31. package/src/sinks/stdout_sink.ts +20 -0
  32. package/src/validate/api_surface_guard.ts +106 -0
  33. package/src/validate/noncompliance.ts +33 -0
  34. package/src/validate/schema_guard.ts +238 -0
  35. package/tests/fanout.test.ts +51 -0
  36. package/tests/fanout_spool.test.ts +96 -0
  37. package/tests/message_constraints.test.ts +7 -0
  38. package/tests/node-shim.d.ts +1 -0
  39. package/tests/record_builder.test.ts +32 -0
  40. package/tests/sequence_monotonic.test.ts +62 -0
  41. package/tests/sinks_file_ndjson.test.ts +53 -0
  42. package/tests/step1_compliance.test.ts +192 -0
  43. package/tools/test_results/generate-test-traceability.js +60 -0
  44. package/tools/test_results/normalize-test-results.js +57 -0
  45. package/tools/test_results/run-tests-then-prebuild.js +103 -0
  46. package/tools/test_results/test-case-map.json +9 -0
  47. package/tsconfig.json +31 -0
  48. package/validators/bootstrap/validate-repo-structure.ts +590 -0
@@ -0,0 +1,223 @@
1
+
2
+ # 🧩 LogSDK Core — Sink / Emitter Contract (v1.0)
3
+
4
+ ## Table of Contents
5
+
6
+ - [Purpose (Non-Negotiable)](#section-purpose-non-negotiable)
7
+ - [1. Conceptual Definition](#section-1-conceptual-definition)
8
+ - [2. Core Sink Contract (Conceptual Interface)](#section-2-core-sink-contract-conceptual-interface)
9
+ - [3. Input Guarantees (What the Core Promises to Sinks)](#section-3-input-guarantees-what-the-core-promises-to-sinks)
10
+ - [4. Sink Guarantees (What Sinks Must Promise)](#section-4-sink-guarantees-what-sinks-must-promise)
11
+ - [5. Sink Categories (Semantic, Not Technical)](#section-5-sink-categories-semantic-not-technical)
12
+ - [6. Failure Semantics (High-Level Only)](#section-6-failure-semantics-high-level-only)
13
+ - [7. What Sinks Are Explicitly Forbidden To Do](#section-7-what-sinks-are-explicitly-forbidden-to-do)
14
+ - [8. Why This Contract Is Minimal (And Correct)](#section-8-why-this-contract-is-minimal-and-correct)
15
+ - [9. Freeze Statement](#section-9-freeze-statement)
16
+
17
+ <a id="section-purpose-non-negotiable"></a>
18
+ ## Purpose (Non-Negotiable)
19
+
20
+ A **Sink (Emitter)** is a **pure output boundary**.
21
+
22
+ Its only responsibility is to:
23
+
24
+ > **Accept an immutable Step Record and persist or forward it elsewhere.**
25
+
26
+ A sink:
27
+
28
+ * does **not** enrich
29
+ * does **not** interpret
30
+ * does **not** derive meaning
31
+ * does **not** influence execution
32
+
33
+ ---
34
+
35
+ <a id="section-1-conceptual-definition"></a>
36
+ ## 1. Conceptual Definition
37
+
38
+ A **Sink** is a component that:
39
+
40
+ 1. Receives a **fully constructed, immutable Step Record**
41
+ 2. Emits it to a destination
42
+ 3. Acknowledges success or failure
43
+ 4. Never mutates the record
44
+
45
+ That is all.
46
+
47
+ ---
48
+
49
+ <a id="section-2-core-sink-contract-conceptual-interface"></a>
50
+ ## 2. Core Sink Contract (Conceptual Interface)
51
+
52
+ Every sink **must** conform to the following conceptual contract:
53
+
54
+ ### Required Capability
55
+
56
+ | Capability | Meaning |
57
+ | -------------- | -------------------------------- |
58
+ | `emit(record)` | Accept one immutable Step Record |
59
+
60
+ ### Optional Capability
61
+
62
+ | Capability | Meaning |
63
+ | ---------- | --------------------------------------- |
64
+ | `flush()` | Ensure buffered records are persisted |
65
+ | `close()` | Finalize resources (files, connections) |
66
+
67
+ ---
68
+
69
+ <a id="section-3-input-guarantees-what-the-core-promises-to-sinks"></a>
70
+ ## 3. Input Guarantees (What the Core Promises to Sinks)
71
+
72
+ Before a record reaches any sink, LogSDK Core guarantees:
73
+
74
+ * record is **canonical**
75
+ * record is **schema-complete**
76
+ * record is **immutable**
77
+ * record is **bounded**
78
+ * record integrity hash is present
79
+ * context is referenced, not embedded
80
+
81
+ Sinks **must not validate semantics** again.
82
+
83
+ ---
84
+
85
+ <a id="section-4-sink-guarantees-what-sinks-must-promise"></a>
86
+ ## 4. Sink Guarantees (What Sinks Must Promise)
87
+
88
+ A compliant sink must guarantee:
89
+
90
+ ### 4.1 Non-Mutation
91
+
92
+ * No field modification
93
+ * No field addition
94
+ * No field removal
95
+ * No re-interpretation
96
+
97
+ Transport metadata (e.g. HTTP headers) is allowed **outside** the record.
98
+
99
+ ---
100
+
101
+ ### 4.2 Deterministic Handling
102
+
103
+ Given the same Step Record:
104
+
105
+ * the sink must behave the same way
106
+ * ordering must be preserved *as received*
107
+
108
+ ---
109
+
110
+ ### 4.3 Isolation
111
+
112
+ A sink:
113
+
114
+ * must not call other sinks
115
+ * must not depend on other sinks
116
+ * must not affect core behavior
117
+
118
+ ---
119
+
120
+ <a id="section-5-sink-categories-semantic-not-technical"></a>
121
+ ## 5. Sink Categories (Semantic, Not Technical)
122
+
123
+ ### 5.1 Authoritative Evidence Sinks (Required)
124
+
125
+ These sinks define **evidence ownership**.
126
+
127
+ Examples:
128
+
129
+ * append-only file sink
130
+ * object storage sink
131
+ * immutable log archive
132
+
133
+ Rules:
134
+
135
+ * long retention
136
+ * append-only semantics
137
+ * replayable
138
+ * system-owned
139
+
140
+ At least **one authoritative sink is mandatory**.
141
+
142
+ ---
143
+
144
+ ### 5.2 Observability Sinks (Optional)
145
+
146
+ These sinks exist for **human visibility**.
147
+
148
+ Examples:
149
+
150
+ * Grafana Loki
151
+ * stdout / console
152
+ * debug streams
153
+
154
+ Rules:
155
+
156
+ * best-effort delivery
157
+ * retention not guaranteed
158
+ * never authoritative
159
+ * may be dropped without governance impact
160
+
161
+ ---
162
+
163
+ <a id="section-6-failure-semantics-high-level-only"></a>
164
+ ## 6. Failure Semantics (High-Level Only)
165
+
166
+ Sink failures are classified conceptually:
167
+
168
+ | Sink Type | Failure Impact |
169
+ | ------------- | ---------------------- |
170
+ | Authoritative | **System-significant** |
171
+ | Observability | **Non-blocking** |
172
+
173
+ **Important:**
174
+ This classification informs **fan-out rules** (next step), not sink behavior itself.
175
+
176
+ ---
177
+
178
+ <a id="section-7-what-sinks-are-explicitly-forbidden-to-do"></a>
179
+ ## 7. What Sinks Are Explicitly Forbidden To Do
180
+
181
+ A sink must never:
182
+
183
+ * inject labels / tags
184
+ * infer severity
185
+ * drop fields
186
+ * reorder records
187
+ * batch across executions
188
+ * correlate records
189
+ * compute metrics
190
+ * call UnifyPlane
191
+ * call other sinks
192
+
193
+ If any occur, the sink is **non-compliant**.
194
+
195
+ ---
196
+
197
+ <a id="section-8-why-this-contract-is-minimal-and-correct"></a>
198
+ ## 8. Why This Contract Is Minimal (And Correct)
199
+
200
+ This design ensures:
201
+
202
+ * replayability
203
+ * deterministic intelligence derivation
204
+ * language neutrality
205
+ * storage freedom
206
+ * safe observability fan-out
207
+ * no governance coupling
208
+
209
+ Anything more would leak responsibility.
210
+
211
+ ---
212
+
213
+ <a id="section-9-freeze-statement"></a>
214
+ ## 9. Freeze Statement
215
+
216
+ This **Sink / Emitter Contract v1.0** is now:
217
+
218
+ * stable
219
+ * minimal
220
+ * sufficient
221
+ * extensible without breaking meaning
222
+
223
+ All current and future sinks **must** conform to this.
@@ -0,0 +1,292 @@
1
+
2
+ # 🧩 LogSDK Core — Canonical Step Record (v1.1)
3
+
4
+ ## Table of Contents
5
+ - [Purpose (Non-Negotiable)](#section-purpose-non-negotiable)
6
+ - [Canonical Record: Field Set](#section-canonical-record-field-set)
7
+ - [1. Identity & Versioning](#section-1-identity-and-versioning)
8
+ - [2. Time (Dual Clock — Mandatory)](#section-2-time-dual-clock-mandatory)
9
+ - [3. System Ownership (Evidence Boundary)](#section-3-system-ownership-evidence-boundary)
10
+ - [4. Execution Correlation (SDK-Derived Only)](#section-4-execution-correlation-sdk-derived-only)
11
+ - [5. Execution Surface (Where This Happened)](#section-5-execution-surface-where-this-happened)
12
+ - [6. Source Location (Best-Effort, Factual)](#section-6-source-location-best-effort-factual)
13
+ - [7. Step Message (Only Human Input)](#section-7-step-message-only-human-input)
14
+ - [8. Context Capsule Reference (Frozen Once)](#section-8-context-capsule-reference-frozen-once)
15
+ - [9. Evidence References (Optional, Structured)](#section-9-evidence-references-optional-structured)
16
+ - [10. Integrity (Normative)](#section-10-integrity-normative)
17
+ - [Explicit Exclusions (Hard Rules)](#section-explicit-exclusions-hard-rules)
18
+ - [Semantic Meaning (Locked)](#section-semantic-meaning-locked)
19
+ - [Determinism Guarantees (Explicit)](#section-determinism-guarantees-explicit)
20
+ - [Freeze Statement](#section-freeze-statement)
21
+ - [Appendix A. Revision Notes (Non-Normative)](#appendix-a-revision-notes-non-normative)
22
+ <a id="section-purpose-non-negotiable"></a>
23
+ ## Purpose (Non-Negotiable)
24
+
25
+ A **Step Record** represents **one execution step** as immutable execution evidence.
26
+
27
+ It must be:
28
+
29
+ * replayable
30
+ * bounded
31
+ * deterministic
32
+ * storage-agnostic
33
+ * derivation-ready
34
+
35
+ It must **not** encode decisions, payloads, intelligence, or interpretation.
36
+
37
+ ---
38
+ <a id="section-canonical-record-field-set"></a>
39
+ ## Canonical Record: Field Set
40
+
41
+ <a id="section-1-identity-and-versioning"></a>
42
+ ### 1. Identity & Versioning
43
+
44
+ | Field | Description |
45
+ | ---------------- | ------------------------------------------------------------ |
46
+ | `record_version` | Fixed identifier of the record contract (e.g. `log.step.v1`) |
47
+ | `record_id` | Unique identifier for this step record |
48
+ | `sequence` | Monotonic sequence number scoped to the SDK instance |
49
+
50
+ **Rules**
51
+
52
+ * `record_version` is immutable and schema-defining
53
+ * `record_id` must be globally unique per process and SDK instance
54
+ * `sequence` must start at `0` and increment by exactly `1`
55
+
56
+ ---
57
+
58
+ <a id="section-2-time-dual-clock-mandatory"></a>
59
+ ### 2. Time (Dual Clock — Mandatory)
60
+
61
+ | Field | Description |
62
+ | ---------------- | ------------------------------------------------------- |
63
+ | `timestamp_utc` | Wall-clock time in UTC (RFC 3339 / ISO-8601 profile) |
64
+ | `monotonic_time` | Monotonic clock value for strict intra-process ordering |
65
+
66
+ **Rules**
67
+
68
+ * Both fields are required
69
+ * Ordering **must never** depend on wall clock alone
70
+ * `monotonic_time` must be strictly increasing per record
71
+
72
+ ---
73
+
74
+ <a id="section-3-system-ownership-evidence-boundary"></a>
75
+ ### 3. System Ownership (Evidence Boundary)
76
+
77
+ | Field | Description |
78
+ | ---------------- | --------------------------------------------------- |
79
+ | `institution` | Owning organization or authority domain |
80
+ | `system_name` | Logical system emitting the step |
81
+ | `system_type` | `process` / `pipeline` / `service` / `content` |
82
+ | `environment` | `local` / `dev` / `staging` / `prod` |
83
+ | `system_version` | Deployed version or build identifier |
84
+ | `instance_id` | Runtime instance identifier (optional but expected) |
85
+
86
+ These fields define **who owns the evidence** and where its trust boundary lies.
87
+
88
+ They must be injected by the SDK or system adapter, never manually set per step.
89
+
90
+ ---
91
+
92
+ <a id="section-4-execution-correlation-sdk-derived-only"></a>
93
+ ### 4. Execution Correlation (SDK-Derived Only)
94
+
95
+ | Field | Description |
96
+ | ---------------- | -------------------------------------------------------- |
97
+ | `trace_id` | Distributed trace identifier (if available) |
98
+ | `span_id` | Span identifier (if available) |
99
+ | `parent_step_id` | Parent step record ID (if hierarchical execution exists) |
100
+
101
+ **Rules**
102
+
103
+ * These fields are **derived automatically**
104
+ * No developer may set or override them
105
+ * Absence is valid if the execution model does not support correlation
106
+
107
+ ---
108
+
109
+ <a id="section-5-execution-surface-where-this-happened"></a>
110
+ ### 5. Execution Surface (Where This Happened)
111
+
112
+ | Field | Description |
113
+ | ------------------ | ------------------------------------------------------- |
114
+ | `surface_type` | `http` / `job` / `worker` / `page` / `cli` / `internal` |
115
+ | `surface_name` | Route, job name, page name, etc. |
116
+ | `surface_instance` | Request ID / job ID / execution ID |
117
+
118
+ **Rules**
119
+
120
+ * Derived by thin SDKs or runtime adapters only
121
+ * Must reflect *execution context*, not business semantics
122
+
123
+ ---
124
+
125
+ <a id="section-6-source-location-best-effort-factual"></a>
126
+ ### 6. Source Location (Best-Effort, Factual)
127
+
128
+ | Field | Description |
129
+ | ----------------- | ----------------------- |
130
+ | `source_file` | Repo-relative file path |
131
+ | `source_module` | Module or package name |
132
+ | `source_function` | Function or method name |
133
+ | `source_line` | Line number (nullable) |
134
+
135
+ **Rules**
136
+
137
+ * Automatically injected by the SDK where possible
138
+ * Must never be developer-supplied
139
+ * Absence (`null`) is acceptable when not reliably obtainable
140
+
141
+ ---
142
+
143
+ <a id="section-7-step-message-only-human-input"></a>
144
+ ### 7. Step Message (Only Human Input)
145
+
146
+ | Field | Description |
147
+ | -------------- | ------------------------------------------------ |
148
+ | `message` | Human-readable step description (bounded string) |
149
+ | `message_code` | Optional registry-defined step code |
150
+
151
+ **Hard Constraints**
152
+
153
+ * String only
154
+ * Non-empty
155
+ * Hard length limit
156
+ * No JSON, arrays, or objects
157
+ * No payloads
158
+ * No free-form metadata
159
+
160
+ This is the **only expressive input** a developer provides.
161
+
162
+ ---
163
+
164
+ <a id="section-8-context-capsule-reference-frozen-once"></a>
165
+ ### 8. Context Capsule Reference (Frozen Once)
166
+
167
+ | Field | Description |
168
+ | ----------------- | ------------------------------------------------- |
169
+ | `context_hash` | Hash reference to frozen context injected at init |
170
+ | `context_version` | Version of the context schema |
171
+
172
+ **Rules**
173
+
174
+ * Context is injected once at SDK initialization
175
+ * Context is normalized, canonicalized, and deeply frozen
176
+ * Context is **never embedded** in records
177
+ * Records reference context **by hash only**
178
+
179
+ ---
180
+
181
+ <a id="section-9-evidence-references-optional-structured"></a>
182
+ ### 9. Evidence References (Optional, Structured)
183
+
184
+ | Field | Description |
185
+ | --------------- | -------------------------------------------------- |
186
+ | `evidence_refs` | Array of references to external evidence artifacts |
187
+
188
+ **Rules**
189
+
190
+ * References only (IDs, URIs, digests)
191
+ * No embedded data
192
+ * No payload material
193
+
194
+ ---
195
+
196
+ <a id="section-10-integrity-normative"></a>
197
+ ### 10. Integrity (Normative)
198
+
199
+ | Field | Description |
200
+ | ---------------- | --------------------------------------- |
201
+ | `record_hash` | Hash of the canonical serialized record |
202
+ | `hash_algorithm` | Algorithm used (explicit, versioned) |
203
+
204
+ **Rules**
205
+
206
+ * Record must be canonically serialized before hashing
207
+ * `record_hash` must **exclude itself** from hash scope
208
+ * Canonical serialization must be deterministic across runtimes
209
+ * UTF-8 encoding is mandatory
210
+
211
+ This guarantees:
212
+
213
+ * immutability
214
+ * tamper detection
215
+ * replay stability
216
+
217
+ ---
218
+ <a id="section-explicit-exclusions-hard-rules"></a>
219
+ ## Explicit Exclusions (Hard Rules)
220
+
221
+ A Step Record **must never contain**:
222
+
223
+ * business payloads
224
+ * metrics or counters
225
+ * severity levels
226
+ * labels or tags
227
+ * inferred meaning
228
+ * decisions or judgments
229
+ * AI outputs
230
+ * free-form metadata
231
+
232
+ Presence of any of the above renders the record **invalid**.
233
+
234
+ ---
235
+ <a id="section-semantic-meaning-locked"></a>
236
+ ## Semantic Meaning (Locked)
237
+
238
+ > A Step Record asserts only:
239
+ > **“This execution step occurred at this point in this system.”**
240
+
241
+ It does **not** assert:
242
+
243
+ * correctness
244
+ * success
245
+ * legitimacy
246
+ * intent
247
+ * impact
248
+
249
+ ---
250
+ <a id="section-determinism-guarantees-explicit"></a>
251
+ ## Determinism Guarantees (Explicit)
252
+
253
+ Given identical:
254
+
255
+ * initialization context
256
+ * execution order
257
+ * SDK version
258
+
259
+ The sequence, structure, and meaning of Step Records must be **replay-stable**, aside from timestamps and identifiers.
260
+
261
+ ---
262
+ <a id="section-freeze-statement"></a>
263
+ ## Freeze Statement
264
+
265
+ This **Canonical Step Record v1.1** is:
266
+
267
+ * language-independent
268
+ * runtime-agnostic
269
+ * ABI-like
270
+ * safe for long-term replay and audit
271
+
272
+ All thin SDKs **must map into this shape exactly**, without extension or semantic enrichment.
273
+
274
+ ---
275
+
276
+ <a id="appendix-a-revision-notes-non-normative"></a>
277
+ ## Appendix A. Revision Notes (Non-Normative)
278
+
279
+ ### Why this update matters
280
+
281
+ * Hashing and determinism are now **normative**, not implied
282
+ * Source and surface fields are clearly bounded
283
+ * The record is now **unambiguously evidence-only**
284
+ * This shape can survive **decades of system evolution**
285
+
286
+ If you want next, the logically correct follow-ups are:
287
+
288
+ * a **canonical JSON Schema** for this record
289
+ * a **hash canonicalization appendix** (RFC-aligned)
290
+ * or a **LogSDK → Step Record conformance checklist**
291
+
292
+ Say which one you want to proceed with.