Skip to content

Commit 5a12922

Browse files
authored
Merge pull request #2 from augmem/fix/runtime-safety-and-retention
Harden runtime safety and optimize durable ingestion
2 parents 70ab115 + 7281d96 commit 5a12922

67 files changed

Lines changed: 5997 additions & 763 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ if(EMSCRIPTEN AND BUILD_WASM)
710710
"_cortext_last_error"
711711
"_cortext_string_free"
712712
"_cortext_process_text_json"
713+
"_cortext_wasm_process_text_json"
713714
"_cortext_process_audio_json"
714715
"_cortext_process_image_json"
715716
"_cortext_consolidate_json"
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
{
2+
"schema": "cortext_flat_storage_cost_summary_v2",
3+
"candidate": 34,
4+
"claim": "best exact candidate; flatness not proven",
5+
"measurement_note": "final timings include runtime reconstruction and working-memory embeddings in the exact sqlite-vec pre-filter mirror, restart hydration of the latest reconstruction, base-only disabled-ablation parity, and authoritative historical-surface rebuild after successful force commits with rollback restoration after failed commits; earlier Candidate 34 timing samples are superseded",
6+
"git_base_sha": "70ab11520b12e28f49fcc5c5019f3a0c80b57dfc",
7+
"content_identity": {
8+
"tracked_diff_sha256_excluding_this_artifact": "38cfef2571937cd76cea6276683bc7559ec558cd8669b9e3b21a937849bbe685",
9+
"untracked_historical_surface_cache_sha256": "a828d25f4da5ff04a8cff7aff84597b8ff95cf97b179aeaf07d642bfbed13904",
10+
"untracked_audit_tool_sha256": "4e02878d0b04ee2183be59853f79b42ec104a3be329ff54f12bf0016f6697f66",
11+
"optimization_section_sha256": "14175a391f1b1b167fe7c9aed8503ef311959a7ef1ed201fe8914ca651e99742",
12+
"generated_manuscript_sha256": "e2b305a7cf7812c54386adc9d05107f2a7b1a468a7474eb1ef3131d8dd458da2"
13+
},
14+
"corpus": {
15+
"full_event_count": 2636,
16+
"private_content_included": false
17+
},
18+
"realtime_500": {
19+
"behavior_sha256": "e03608f44c470951e58c1e414dd6b015e742317e6cdbb6b2e5122bb7ab62be7f",
20+
"logical_database_sha256": "508d06031973cf593939bd44a6d9e37c921c67467fe815cf7e828e6f385b9a74",
21+
"logical_table_counts": {
22+
"associations": 9091,
23+
"memories": 521,
24+
"signals": 521
25+
},
26+
"mean_process_ms": 4.539976482,
27+
"mean_total_ms": 10.693155648,
28+
"wall_ms": 5529,
29+
"private_profile_sha256": "0ab62e4ea8d42a10469e117d18f273a295930627066fe3a7f2adf57b7942704a",
30+
"private_database_file_sha256": "c3ab3ead7609c001de191ed4d9a7d9aed20a29e9a442b66466c6ead0273097c3",
31+
"audit_sha256": "4368fb1550547c7d721aaa8820d72b2d290f6370b685addb7614cfef22b0a592"
32+
},
33+
"realtime_2636": {
34+
"behavior_sha256": "4e728353eab989086481217cd140930875b112dcccb1fe372acdefc9b16c6bb8",
35+
"logical_database_sha256": "a2a538e619b9b10b1a5f2892993a168e7b0f8be31cd0eaa912937f9d26a2ddfe",
36+
"logical_table_counts": {
37+
"associations": 57643,
38+
"memories": 2657,
39+
"signals": 2657
40+
},
41+
"mean_process_ms": 8.56041844688923,
42+
"mean_total_ms": 14.550963581942321,
43+
"wall_ms": 39338,
44+
"memory_storage_late_early_ratio": 2.0637580798306874,
45+
"memory_storage_theil_sen_ms_per_message": 0.0006847791920168069,
46+
"memory_storage_bootstrap_95_upper_ms_per_message": 0.0007039323847373954,
47+
"supersession_late_early_ratio": 2.5286640702899343,
48+
"supersession_theil_sen_ms_per_message": 0.0006861894281249999,
49+
"supersession_bootstrap_95_upper_ms_per_message": 0.0006946835751420457,
50+
"process_late_early_ratio": 1.7394144434401446,
51+
"messages_per_second_late_early_ratio": 0.6922616419820202,
52+
"private_profile_sha256": "c9aca1d263ebeffe3241f5c5ba7fe679442a8279d508c1e12107b78edb594ad4",
53+
"private_database_file_sha256": "477e01bbafee145fbdc79440bea634d7dca43935248dbba9df2d6978e78ae20b",
54+
"audit_sha256": "5208e981886d251d06532d9925142a55c1a584592fd4d504d21cb5c16c293db3"
55+
},
56+
"durable_1000": {
57+
"behavior_sha256": "44965174958b968ca2672a4baed0e68b2c65c770ffa0477a235672d9282a42b9",
58+
"logical_database_sha256": "673a73733aefc6739ec3b6160850c7ec08d68cb2712be4ddf397541458a96df5",
59+
"logical_table_counts": {
60+
"associations": 19845,
61+
"memories": 1021,
62+
"signals": 1021
63+
},
64+
"mean_process_ms": 6.509920871,
65+
"mean_total_ms": 12.456616908,
66+
"wall_ms": 12827,
67+
"memory_storage_late_early_ratio": 1.6338130397,
68+
"supersession_late_early_ratio": 2.0707513586,
69+
"process_late_early_ratio": 1.4147756438,
70+
"messages_per_second_late_early_ratio": 0.8446645486,
71+
"private_profile_sha256": "b95d527370f0a3d766bc37c4e9eb1a8749aa01e313a931f294c7bdc60d6b3a03",
72+
"private_database_file_sha256": "8e22e9e1b4d14b984488b335213919d2430cdb5e4358feba92e984832e2c5e9c",
73+
"audit_sha256": "c08b966819329792af43717d58f3b39f056326947971873de5baee31896c58b2"
74+
},
75+
"midpoint_consolidation_1500": {
76+
"event_count": 1500,
77+
"forced_consolidations": 2,
78+
"consolidation_messages": [750, 1500],
79+
"behavior_sha256": "a86d5aa3ed1ae945a794fd6b071f3d80bdada008a66cc2076313d7da404c6a5a",
80+
"logical_database_sha256": "4751e7d7b6711d7e968ff7c31761150a22fab9735dbd4c961b3227f4bfa3bf81",
81+
"logical_table_counts": {
82+
"associations": 3500,
83+
"memories": 1524,
84+
"signals": 1523
85+
},
86+
"pre_repair": {
87+
"mean_process_ms": 250.744265,
88+
"mean_total_ms": 257.707038,
89+
"wall_ms": 388127,
90+
"consolidation_total_ms": 1085.133,
91+
"post_midpoint_mean_process_ms": 496.352139,
92+
"post_midpoint_mean_total_ms": 504.693886,
93+
"post_midpoint_memory_storage_ms": 485.852829,
94+
"post_midpoint_supersession_ms": 485.492936,
95+
"private_profile_sha256": "b4707eb343450d47f75d204fc1ee23dbfeb8c97803ff2cd3cb7b7319fa4c9d84",
96+
"private_database_file_sha256": "8c0f841967d1e9d0bd4869c58c9c40158c9e61ce05af770029f3e042e57d3f73",
97+
"audit_sha256": "2afa8e0e469423a68f1a90ce361b9a3b3ac96cc0124d5688ca4f87082705caf2"
98+
},
99+
"post_repair": {
100+
"mean_process_ms": 6.518981,
101+
"mean_total_ms": 12.506988,
102+
"wall_ms": 19586,
103+
"consolidation_total_ms": 294.829,
104+
"post_midpoint_mean_process_ms": 8.097541,
105+
"post_midpoint_mean_total_ms": 14.470518,
106+
"post_midpoint_memory_storage_ms": 1.116600,
107+
"post_midpoint_supersession_ms": 0.791841,
108+
"private_profile_sha256": "3b9e7203769b01c94b290eee62ffbd1879b38c20ff97baeac4e0b3a7230b544f",
109+
"private_database_file_sha256": "dafc08954f15bd31abf01fdf100a287439654b39a790cfefc8222360a1dfcc1f",
110+
"audit_sha256": "391ef9de875ef56d1d66171549cb91593c298270c7ea2908c0dde3c664c3cdca"
111+
}
112+
},
113+
"current_midpoint_consolidation_2636": {
114+
"event_count": 2636,
115+
"forced_consolidations": 2,
116+
"consolidation_messages": [1318, 2636],
117+
"behavior_sha256": "8f0fcdaeb223fa0bb032bcc7c0c8e386547ec0f64b7c8d7503d32846936506ec",
118+
"logical_database_sha256": "b44de2500403fbf9a73486ddb3580f126b93bc49e4fb08018c0cbc20540df25d",
119+
"logical_table_counts": {
120+
"associations": 6052,
121+
"memories": 2660,
122+
"signals": 2659
123+
},
124+
"mean_process_ms": 8.189805,
125+
"mean_total_ms": 14.198027,
126+
"wall_ms": 38929,
127+
"consolidation_total_ms": 542.213,
128+
"post_midpoint_mean_process_ms": 10.088494,
129+
"post_midpoint_mean_total_ms": 16.255952,
130+
"post_midpoint_memory_storage_ms": 1.587111,
131+
"post_midpoint_supersession_ms": 1.249826,
132+
"private_profile_sha256": "53464b4ce300e9455d54684450fda93315190a620ffbcc13fa0cd39c630fa44f",
133+
"private_database_file_sha256": "9e2bab4bd05857a48b6da35881aee4aa8fc4abc8e4e42640851cb42fc9061aae",
134+
"audit_sha256": "6e4f1e0e42d6099cb6ba319f96e4b3259a8b07c08f9f56a0804ecdec89f5675d",
135+
"full_pre_repair_comparator_available": false
136+
},
137+
"standard_eviction_frontier_estimate": {
138+
"pressure_gate_bytes": 500000000,
139+
"central_message_count": 27445,
140+
"planning_range_messages": [26687, 30542],
141+
"extrapolation_multiple_over_measured_corpus": 10.4,
142+
"projected_engine_process_ms": 89.77907474012856,
143+
"projected_engine_writes_per_second": 11.138452951,
144+
"projected_sequential_total_ms": 103.66147944884663,
145+
"projected_sequential_messages_per_second": 9.646784952,
146+
"actual_eviction_measured": false,
147+
"reason_actual_eviction_not_measured": "pressure only permits eviction; age and strength predicates also apply, and the measured corpus has last_consolidation_ts=0"
148+
},
149+
"gates": {
150+
"behavior_exact": true,
151+
"logical_database_exact": true,
152+
"storage_slope": true,
153+
"storage_late_early_ratio": false,
154+
"throughput": false,
155+
"flatness_proven": false
156+
},
157+
"proof_not_claimed": [
158+
"flat storage cost",
159+
"flat end-to-end throughput",
160+
"complete full-corpus pre-repair midpoint-consolidation comparison",
161+
"post-eviction throughput",
162+
"other corpora or hardware",
163+
"production deployment",
164+
"merge or release readiness"
165+
]
166+
}

bindings/dart/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ void main() {
5050

5151
## API
5252

53+
<!-- public Dart binding API and image contract matching bindings/dart/lib/src/cortext_wrapper.dart -->
54+
5355
- `Config`: Focus/Sensitivity/Stability, mechanism toggles, and signal-filter
5456
toggles.
5557
- `processText`, `processAudio`, `processImage`: decoded JSON maps.
@@ -58,4 +60,5 @@ void main() {
5860
- `consolidate`, `flush`, `reset`, `close`.
5961

6062
Audio input is 16 kHz mono float32 PCM. Image input is row-major RGB/RGBA bytes
61-
with explicit dimensions.
63+
with explicit dimensions. Non-positive dimensions and buffers smaller than
64+
`width * height * channels` are rejected before native inference.

bindings/dart/lib/src/cortext_wrapper.dart

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ final class ProcessOptions {
6767

6868
enum Retention { natural, durable, boundary, ephemeral }
6969

70+
void _validateImageBuffer(Uint8List data, int width, int height, int channels) {
71+
if (width <= 0 || height <= 0 || channels <= 0) {
72+
throw ArgumentError('width, height, and channels must be positive');
73+
}
74+
if (width > 0x7fffffff || height > 0x7fffffff || channels > 0x7fffffff) {
75+
throw ArgumentError('image dimensions exceed the native int range');
76+
}
77+
final expected = width * height * channels;
78+
if (data.length < expected) {
79+
throw ArgumentError(
80+
'image buffer is smaller than width * height * channels',
81+
);
82+
}
83+
}
84+
7085
final class CortextLibrary {
7186
CortextLibrary._(this.dynamicLibrary)
7287
: bindings = CortextBindings(dynamicLibrary);
@@ -269,10 +284,7 @@ final class Cortext {
269284
final textPointer = text.toNativeUtf8();
270285
try {
271286
return _takeJsonString(
272-
_library.bindings.cortext_embed_text_json(
273-
_handle,
274-
textPointer.cast(),
275-
),
287+
_library.bindings.cortext_embed_text_json(_handle, textPointer.cast()),
276288
);
277289
} finally {
278290
malloc.free(textPointer);
@@ -349,15 +361,15 @@ final class Cortext {
349361
..size = media.data.length
350362
..mimetype = mediaMimePointer.cast();
351363
}
352-
final raw =
353-
_library.bindings.cortext_process_audio_with_media_json_with_options(
354-
_handle,
355-
pcmPointer,
356-
pcm.length,
357-
sourcePointer.cast(),
358-
mediaPointer,
359-
optionsPointer,
360-
);
364+
final raw = _library.bindings
365+
.cortext_process_audio_with_media_json_with_options(
366+
_handle,
367+
pcmPointer,
368+
pcm.length,
369+
sourcePointer.cast(),
370+
mediaPointer,
371+
optionsPointer,
372+
);
361373
return _takeJsonString(raw);
362374
} finally {
363375
malloc.free(sourcePointer);
@@ -430,6 +442,7 @@ final class Cortext {
430442
ProcessOptions options = const ProcessOptions(),
431443
]) {
432444
_ensureOpen();
445+
_validateImageBuffer(data, width, height, channels);
433446
final sourcePointer = sourceId.toNativeUtf8();
434447
final optionsPointer = _allocateProcessOptions(options);
435448
Pointer<Uint8> dataPointer = nullptr;
@@ -467,6 +480,7 @@ final class Cortext {
467480
ProcessOptions options = const ProcessOptions(),
468481
]) {
469482
_ensureOpen();
483+
_validateImageBuffer(data, width, height, channels);
470484
final sourcePointer = sourceId.toNativeUtf8();
471485
final optionsPointer = _allocateProcessOptions(options);
472486
Pointer<Uint8> dataPointer = nullptr;
@@ -495,17 +509,17 @@ final class Cortext {
495509
..size = media.data.length
496510
..mimetype = mediaMimePointer.cast();
497511
}
498-
final raw =
499-
_library.bindings.cortext_process_image_with_media_json_with_options(
500-
_handle,
501-
dataPointer,
502-
width,
503-
height,
504-
channels,
505-
sourcePointer.cast(),
506-
mediaPointer,
507-
optionsPointer,
508-
);
512+
final raw = _library.bindings
513+
.cortext_process_image_with_media_json_with_options(
514+
_handle,
515+
dataPointer,
516+
width,
517+
height,
518+
channels,
519+
sourcePointer.cast(),
520+
mediaPointer,
521+
optionsPointer,
522+
);
509523
return _takeJsonString(raw);
510524
} finally {
511525
malloc.free(sourcePointer);
@@ -560,13 +574,9 @@ final class Cortext {
560574
);
561575
}
562576

563-
String embedImageJson(
564-
Uint8List data,
565-
int width,
566-
int height,
567-
int channels,
568-
) {
577+
String embedImageJson(Uint8List data, int width, int height, int channels) {
569578
_ensureOpen();
579+
_validateImageBuffer(data, width, height, channels);
570580
Pointer<Uint8> dataPointer = nullptr;
571581
try {
572582
if (data.isNotEmpty) {
@@ -588,12 +598,7 @@ final class Cortext {
588598
}
589599
}
590600

591-
Float32List embedImage(
592-
Uint8List data,
593-
int width,
594-
int height,
595-
int channels,
596-
) {
601+
Float32List embedImage(Uint8List data, int width, int height, int channels) {
597602
return _decodeEmbedding(embedImageJson(data, width, height, channels));
598603
}
599604

bindings/go/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,17 @@ func main() {
5555

5656
## API
5757

58+
<!-- public Go binding API and Config semantics matching bindings/go/cortext.go -->
59+
5860
- `Config`: Focus/Sensitivity/Stability, mechanism toggles, and signal-filter
59-
toggles. Pass `nil` to `New` for native defaults.
61+
toggles. Fields are optional pointers, so omitted values retain native
62+
defaults while explicit zero/false values remain representable. Use
63+
`cortext.Ptr(value)` in struct literals, or pass `nil` to `New` for all
64+
native defaults.
6065
- `ProcessText`, `ProcessAudio`, `ProcessImage`: decoded JSON context maps.
6166
- `ProcessTextJSON`, `ProcessAudioJSON`, `ProcessImageJSON`: raw JSON bytes.
6267
- `EmbedText`, `EmbedAudio`, `EmbedImage`: embed-only helpers.
6368
- `Consolidate`, `Flush`, `Reset`, `Close`.
6469

6570
Audio input is 16 kHz mono float32 PCM. Image input is row-major RGB/RGBA bytes
66-
with explicit dimensions.
71+
with explicit dimensions; undersized buffers are rejected before entering C.

0 commit comments

Comments
 (0)