Implement CogDiod feature plan: kernel hardening, atom types, pattern matching#7
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 10 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
| } | ||
|
|
||
| /* Destroy the atom */ | ||
| cogdiod_destroy_atom(k, gc_uuids[i]); |
There was a problem hiding this comment.
GC leaves dangling channels
High Severity
When cogdiod_gc_sweep destroys an atom, its LimboChannel objects aren't properly unlinked from neighbors or freed. This leaves other atoms with stale pointers to these orphaned channels, which can lead to graph corruption, memory leaks, and crashes during channel access.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
|
|
||
| fclose(f); | ||
| fprintf(stderr, "[cogdiod] loaded %u atoms from %s\n", ac, path); | ||
| return k; |
There was a problem hiding this comment.
Load drops saved links
High Severity
The cogdiod_load function reads outgoing channel UUIDs but doesn't use them to re-establish LimboChannel connections. This leaves loaded atoms isolated, destroying graph topology and breaking features like messaging, ECAN, and pattern matching.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
|
|
||
| if (pos < sizeof(tmp)) { | ||
| /* Close the JSON array */ | ||
| if (!truncated && pos < sizeof(tmp)) { |
There was a problem hiding this comment.
Load null package deref
Medium Severity
When /ai/atoms/ listings exceed the buffer limit, the distyx_handle_list_atoms function incorrectly omits the closing ] from the JSON array. This sends malformed JSON to clients, causing parsing errors despite a successful operation.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
| pthread_mutex_unlock(&ch->lock); | ||
| } | ||
| ch = ch->in_next; | ||
| } |
There was a problem hiding this comment.
GC notifies dying atom
High Severity
cogdiod_gc_sweep queues MSG_DESTROY on the collected atom’s incoming channels, so messages land in that atom’s own mailboxes. Neighbors are not woken on their incoming queues, and outgoing neighbors are never notified, so the stated pre-destroy neighbor signaling does not occur.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
| /* Store in kernel struct for use by ecan_diffuse */ | ||
| /* For now, these are hardcoded in cogdiod_ecan_diffuse */ | ||
| fprintf(stderr, "[cogdiod] ECAN params set: spread=%.2f decay=%.2f rent=%.2f\n", | ||
| spread, decay, rent); |
There was a problem hiding this comment.
ECAN params not applied
Medium Severity
cogdiod_set_ecan_params is exported in the public header but only logs arguments; spread, decay, and rent are not stored or used by cogdiod_ecan_diffuse, rent, or normalization.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
|
|
||
| pch = pch->out_next; | ||
| gch = gch->out_next; | ||
| } |
There was a problem hiding this comment.
Unify lacks cycle guard
Medium Severity
unify recurses over outgoing channels with no visited set or depth limit. Cyclic graphs can cause unbounded recursion and stack overflow during pattern matching.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
| a = a->ht_next; | ||
| } | ||
| } | ||
| pthread_rwlock_unlock(&k->pool_lock); |
There was a problem hiding this comment.
Match re-locks pool rwlock
High Severity
cogdiod_match holds k->pool_lock for read while scanning the pool, but unify resolves link targets via cogdiod_get_atom, which attempts another read lock on the same non-recursive pthread_rwlock. That nested locking is undefined and typically deadlocks the first pattern-match call.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
| a->av.sti = sti; | ||
| a->av.lti = lti; | ||
| a->state = ATOM_ALIVE; | ||
| a->package = cogdiod_get_package(k, type_id); |
There was a problem hiding this comment.
Loaded atoms skip package refs
High Severity
cogdiod_load assigns a->package = cogdiod_get_package without checking for NULL or bumping ref_count, unlike cogdiod_spawn. Destroying a loaded atom then dereferences a null package or decrements refs that were never incremented.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
| k->atom_pool[b] = a; | ||
| k->atom_count++; | ||
| if (uuid >= k->next_uuid) k->next_uuid = uuid + 1; | ||
| pthread_rwlock_unlock(&k->pool_lock); |
There was a problem hiding this comment.
Load ignores kernel STI total
Medium Severity
Load restores per-atom av.sti but never adds those values to k->total_sti. Kernel-wide STI accounting stays at zero while atoms hold attention, so rent collection and normalization operate on incorrect totals after restore.
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.
| int cogdiod_start(CogDiodKernel* k) { | ||
| k->running = true; | ||
|
|
||
| /* Pre-allocate run queue */ |
There was a problem hiding this comment.
New links decay immediately
Medium Severity
New channels set last_fire_time to 0 while cogdiod_hebbian_decay_all treats channels with now - last_fire_time > 60 as inactive. Fresh links therefore decay on the first decay pass instead of after a minute without firing.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4d6c927. Configure here.


Implements Phases 1, 2, 3, and 6 from the exhaustive feature implementation plan in Issue #6.
Phase 1: Kernel Hardening
av.stidescendingcogdiod_gc_sweep()evicts atoms with low LTI/STI, sendsMSG_DESTROYto neighborscogdiod_save()/cogdiod_load()for kernel state serializationcogdiod_ecan_collect_rent()+cogdiod_ecan_normalize()for STI equilibriumcogdiod_get_tv_history()exposes ring buffer via APIPhase 2: Atom Types
12 new packages with Dis VM bytecode stubs:
Phase 3: Pattern Matching
DisTyx query path:
GET /ai/query/<bind_link_uuid>Phase 6: ECAN Enhancements
cogdiod_hebbian_decay_all(): Decay weight of inactive channelscogdiod_prune_weak_channels(): Remove channels below thresholdcogdiod_set_ecan_params(): Runtime configuration for spread/decay/rentBug Fixes
distyx_handle_list_atoms()with duplicate code block causing build failurefirst = 0assignment in link handlerNote
Medium Risk
Touches core scheduling, atom GC, and save/load on shared kernel state; persistence load omits graph relinks and the query HTTP path does not invoke matching yet, so behavior can diverge from callers’ expectations.
Overview
Expands the CogDiod kernel and build with Phase 1/2/3/6 capabilities: scheduling, memory management, persistence, ECAN/Hebbian helpers, many new atom types, and a pattern-matching core.
Kernel (
cogdiod_kernel.c/cogdiod.h): The worker run queue switches from a fixed-size ring buffer to an STI-priority max-heap (growable, pop highest STI). New APIs add GC sweep (low LTI/STI sleeping atoms →MSG_DESTROYthen destroy), binary save/load (CGDSformat; load restores atoms but skips relinking outgoing edges), STI rent + normalization,cogdiod_get_tv_history, and Hebbian decay / weak-channel pruning plus acogdiod_set_ecan_paramshook that currently only logs (diffusion still hardcoded).Atom types: The Makefile links 12 new Elm stub packages (nodes, links, boolean ops,
BindLink) with PLN/ECAN-oriented bytecode stubs.Pattern matching: New
include/pattern_match.handsrc/pm/unify.cimplementunify,cogdiod_match(pool scan + callback), and JSON binding export.distyxadds/ai/query/<bind_link_uuid>but still returnsmatches: 0without callingcogdiod_match.DisTyx fix:
distyx_handle_list_atomscloses the JSON array correctly and caps output toDISTYX_MSIZE.Reviewed by Cursor Bugbot for commit 4d6c927. Bugbot is set up for automated code reviews on this repo. Configure here.