Skip to content

Commit 42dab96

Browse files
committed
docs(plan-338): file katgpt-sense cross-module decoupling plan (Issue 007 Tier 2 #7)
Audit-driven plan for the last blocked Phase E Tier 2 promotion. Cross-module coupling map: - sense/lod.rs -> crate::slod::ScaleBoundary - sense/reconstruction.rs -> crate::temporal_deriv::TemporalDerivativeKernel - sense/spectral_threat.rs -> crate::linoss::{LinOSSCell, LinOSSState} - all sense files -> crate::types::{SenseKind, SenseModule, TernaryDir} (in katgpt-types) Evaluates 4 strategies (A minimal, B 4 sibling crates, C hybrid, D defer). Recommends C: co-extract ScaleBoundary + TemporalDerivativeKernel to katgpt-types, keep linoss + spectral_threat.rs as composition in katgpt-core, promote ~4,609 LOC substrate as new katgpt-sense crate. Rejects B (zero external consumers for 3 of 4 proposed sibling crates violates the publishable-leaf criterion from Plan 008).
1 parent 380dc9e commit 42dab96

1 file changed

Lines changed: 273 additions & 0 deletions

File tree

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
# Plan 338: katgpt-sense Cross-Module Decoupling (Issue 007 Phase E Tier 2 #7)
2+
3+
> **Origin:** [Issue 007](../../../riir-ai/.issues/007_katgpt_runtime_ip_exfiltration_from_public_mit_repo.md) Phase E Tier 2 #7
4+
> **Status:** Active — options analysis done, awaiting decision
5+
> **Branch:** `develop`
6+
> **Created:** 2026-06-28
7+
> **Cross-repo:** katgpt-rs only (sense has no riir-ai consumers per grep)
8+
9+
---
10+
11+
## TL;DR
12+
13+
The remaining `katgpt-core::sense` substrate (5,232 LOC across 10 files) is the
14+
last blocked Tier 2 promotion. The blocker is **three internal-to-katgpt-core
15+
dependencies** that no prior plan anticipated:
16+
17+
| Sense File | External katgpt-core dep | Source |
18+
|---|---|---|
19+
| `sense/lod.rs` | `crate::slod::ScaleBoundary` | `katgpt-core/src/slod.rs` (1,047 LOC) |
20+
| `sense/reconstruction.rs` | `crate::temporal_deriv::TemporalDerivativeKernel` (gated `temporal_deriv`) | `katgpt-core/src/temporal_deriv.rs` (424 LOC) |
21+
| `sense/spectral_threat.rs` | `crate::linoss::{LinOSSCell, LinOSSState}` | `katgpt-core/src/linoss.rs` (938 LOC) |
22+
| All sense files | `crate::types::{SenseKind, SenseModule, TernaryDir}` | `katgpt-types` ✅ already extracted |
23+
24+
**Recommended strategy: C — Hybrid co-extraction.**
25+
Co-extract the two generic primitives (`ScaleBoundary`, `TemporalDerivativeKernel`)
26+
to `katgpt-types`; promote `katgpt-sense` as a new crate with cross-crate deps on
27+
`katgpt-types` only; keep `linoss` in `katgpt-core` (it has exactly one consumer
28+
`sense/spectral_threat.rs` — which stays in `katgpt-core` as a composition
29+
module, not promoted with the generic substrate).
30+
31+
**Why not the alternatives:**
32+
- **A (minimal co-extract)**: only unblocks `lod.rs`, leaves `temporal_deriv` +
33+
`linoss` cycles unresolved.
34+
- **B (4 sibling crates)**: over-engineered for the LOC budget. `katgpt-linoss`
35+
would ship with exactly 1 consumer (itself a 623 LOC file). Three new crates
36+
for ~2,400 LOC of primitives.
37+
- **D (defer indefinitely)**: leaves 5,232 LOC of clearly publishable octree /
38+
reconstruction / bake / sector machinery stranded in the mega-crate.
39+
40+
Strategy C extracts one new crate (~4,600 LOC after splitting out
41+
`spectral_threat`), promotes two generic primitives to the leaf, and leaves
42+
one tightly-coupled pair (`linoss` + `spectral_threat`) inside katgpt-core
43+
where they belong as composition-layer code.
44+
45+
---
46+
47+
## Detailed Options Analysis
48+
49+
### Option A — Co-extract `ScaleBoundary` to katgpt-types only
50+
51+
Move just the `ScaleBoundary` struct (small POD: `sigma`, `lambda`, etc.) to
52+
`katgpt-types/src/enums.rs` or a new `spectral.rs` submodule.
53+
54+
- `sense/lod.rs` then depends only on `katgpt-types` — promoted cleanly.
55+
- `sense/reconstruction.rs` still depends on `temporal_deriv`**stays blocked**.
56+
- `sense/spectral_threat.rs` still depends on `linoss`**stays blocked**.
57+
58+
**Verdict:** Unblocks 1 of 3 problem files. The remaining 2 keep `katgpt-sense`
59+
dependent on katgpt-core. **Reject** — doesn't achieve the goal.
60+
61+
### Option B — Extract 4 sibling crates
62+
63+
Promote `katgpt-slod`, `katgpt-temporal-deriv`, `katgpt-linoss`, `katgpt-sense`
64+
as four new public crates.
65+
66+
- Each is independently publishable.
67+
- katgpt-sense depends on the other three.
68+
69+
**Math:**
70+
71+
| Crate | LOC | External consumers (outside katgpt-core) |
72+
|---|---|---|
73+
| katgpt-slod | 1,047 | 0 (only `rtdc.rs` + `sense/lod.rs` use it, both internal) |
74+
| katgpt-temporal-deriv | 424 | 0 (only `cgsp/derivative_curiosity.rs`, `delta_mem/state.rs`, `sense/reconstruction.rs` — all internal) |
75+
| katgpt-linoss | 938 | 0 (only `sense/spectral_threat.rs` — 1 internal consumer) |
76+
| katgpt-sense | 5,232 | downstream via re-export (TBD) |
77+
78+
**Verdict:** Three crates with **zero external consumers** violates the
79+
"publishable-leaf" criterion established in Plan 008. The whole point of
80+
promotion is to surface public substrate; these are private katgpt-core
81+
internals. **Reject** — over-engineered, leaks internal layering decisions.
82+
83+
### Option C — Hybrid co-extraction ✅ RECOMMENDED
84+
85+
**Three moves:**
86+
87+
1. **`ScaleBoundary` → katgpt-types.** The struct is a small POD
88+
(`sigma: f32`, `lambda: f32`, etc.) — fits naturally alongside other
89+
generic spectral primitives. Co-extract ~50 LOC.
90+
91+
2. **`TemporalDerivativeKernel` → katgpt-types.** This is a generic
92+
temporal-primitive (424 LOC file, but the public surface is one struct +
93+
one free fn `sigmoid_surprise_gate`). Co-extract the kernel struct + gate
94+
fn; tests stay in katgpt-core.
95+
96+
3. **`linoss` stays in katgpt-core.** It has exactly one consumer
97+
(`sense/spectral_threat.rs`). Co-promoting them would be more correct than
98+
splitting. The 623 LOC `spectral_threat.rs` file stays in katgpt-core as a
99+
**composition module** (mirrors how `forward_hla` stayed in katgpt-core
100+
while the HLA substrate got promoted in Tier 2 #4).
101+
102+
**Net result:**
103+
- New crate `katgpt-sense` (10 → 9 files after `spectral_threat.rs` stays):
104+
~4,609 LOC.
105+
- katgpt-types grows by ~470 LOC (ScaleBoundary + TemporalDerivativeKernel).
106+
- katgpt-core keeps `linoss.rs` (938 LOC) + `sense/spectral_threat.rs` (623
107+
LOC) = 1,561 LOC of composition code.
108+
- Re-export shim: `#[cfg(feature = "sense_composition")] pub use katgpt_sense as sense;`
109+
in `katgpt-core/src/lib.rs`.
110+
- `sense/spectral_threat.rs` becomes `katgpt_core::sense_threat` (or similar)
111+
and is re-exported alongside the substrate via a second shim.
112+
113+
**Why this is the GOAT:**
114+
- Matches the established Tier 1/Tier 2 pattern (substrate out, composition stays).
115+
- Only 1 new crate (not 4).
116+
- Generic primitives go to the leaf where they get widest reuse.
117+
- Tightly-coupled `linoss + spectral_threat` stay together in katgpt-core as
118+
composition code — exactly where they belong.
119+
120+
### Option D — Defer indefinitely
121+
122+
Document that `katgpt-sense` is too entangled to extract and accept it as
123+
part of katgpt-core's integrated substrate.
124+
125+
**Verdict:** Leaves 5,232 LOC of clearly publishable machinery (octree,
126+
reconstruction, bake, sector) inside the mega-crate. The octree and
127+
reconstruction files alone (`octree.rs` + `reconstruction.rs` + `serialize.rs`
128+
= 2,421 LOC) are pure substrate with zero deps outside `katgpt-types`.
129+
**Reject** — leaves real value stranded.
130+
131+
---
132+
133+
## Phased Task Breakdown (Strategy C)
134+
135+
### Phase 1 — Co-extract `ScaleBoundary` to katgpt-types
136+
137+
- [ ] **T1.1** Audit `katgpt-core/src/slod.rs` — extract the `ScaleBoundary`
138+
struct definition + its derives/impls into a new katgpt-types module
139+
(`katgpt-types/src/spectral.rs` or extend `enums.rs`).
140+
- [ ] **T1.2** Update `katgpt-core/src/slod.rs` to re-export
141+
`katgpt_types::ScaleBoundary` (mirror the leaky_core / depth_invariance
142+
pattern from Tier 1 #3).
143+
- [ ] **T1.3** Run GOAT gate:
144+
- `cargo check -p katgpt-types` clean.
145+
- `cargo check -p katgpt-core --features slod` clean.
146+
- `cargo test -p katgpt-core --features slod --lib` — test count matches
147+
pre-extraction baseline.
148+
- `cargo check -p riir-engine` clean (no API surface change).
149+
150+
### Phase 2 — Co-extract `TemporalDerivativeKernel` to katgpt-types
151+
152+
- [ ] **T2.1** Audit `katgpt-core/src/temporal_deriv.rs` (424 LOC) — extract
153+
the public API surface (`TemporalDerivativeKernel` struct, constructor,
154+
`process`/`step` methods, `sigmoid_surprise_gate` free fn) into
155+
`katgpt-types/src/temporal.rs`.
156+
- [ ] **T2.2** Tests stay in katgpt-core (they exercise the kernel through
157+
the re-export).
158+
- [ ] **T2.3** Update `katgpt-core/src/temporal_deriv.rs` to be a re-export
159+
shim: `pub use katgpt_types::temporal::*;`. Preserve the
160+
`#[cfg(feature = "temporal_deriv")]` gate.
161+
- [ ] **T2.4** Run GOAT gate:
162+
- `cargo check -p katgpt-types --features temporal_deriv` (if feature is
163+
propagated to katgpt-types — likely yes, since the kernel is now there).
164+
- `cargo check -p katgpt-core --features temporal_deriv` clean.
165+
- `cargo test -p katgpt-core --features temporal_deriv --lib` — test count
166+
matches.
167+
- `cargo check -p katgpt-core --features delta_mem` clean (delta_mem/state.rs
168+
consumes the kernel).
169+
170+
### Phase 3 — Promote katgpt-sense (substrate minus spectral_threat)
171+
172+
- [ ] **T3.1** Create `crates/katgpt-sense/` with `Cargo.toml` declaring
173+
deps: `katgpt-types` only (after Phase 1+2, all external deps resolve here).
174+
- [ ] **T3.2** `git mv` 9 files from `crates/katgpt-core/src/sense/`
175+
`crates/katgpt-sense/src/`:
176+
- `bake.rs`, `lod.rs`, `mod.rs` (→ `lib.rs`), `octree.rs`,
177+
`reconstruction.rs`, `reconstruction_depth_invariance.rs`,
178+
`schema_centroid.rs`, `sector.rs`, `serialize.rs`.
179+
- [ ] **T3.3** KEEP `spectral_threat.rs` in `katgpt-core/src/sense_threat.rs`
180+
(rename to avoid clash). It needs `crate::linoss` which stays in
181+
katgpt-core.
182+
- [ ] **T3.4** Rename `mod.rs``lib.rs`, update internal paths:
183+
- `crate::<module>::``crate::` (within the new crate).
184+
- `crate::types::``katgpt_types::`.
185+
- `crate::slod::``katgpt_types::` (after Phase 1).
186+
- `crate::temporal_deriv::``katgpt_types::temporal::` (after Phase 2).
187+
- [ ] **T3.5** Add re-export shims in `katgpt-core/src/lib.rs`:
188+
```rust
189+
#[cfg(feature = "sense_composition")]
190+
pub use katgpt_sense as sense;
191+
```
192+
The `spectral_threat` module stays as a separate katgpt-core mod and is
193+
consumed via `katgpt_core::sense_threat::*` or re-exported through the
194+
`sense` alias if downstream compat requires.
195+
- [ ] **T3.6** Feature-forwarding: `sense_composition` Cargo feature in
196+
katgpt-core changes from `[]` to `["dep:katgpt-sense"]`. Default-on / opt-in
197+
status preserved (audit current default-on list to confirm).
198+
- [ ] **T3.7** Update katgpt-core's `sense/mod.rs` (if it survives) or remove
199+
it (likely removed — the substrate moved out).
200+
201+
### Phase 4 — Verification (cross-cutting)
202+
203+
- [ ] **T4.1** `cargo check -p katgpt-sense` clean.
204+
- [ ] **T4.2** `cargo test -p katgpt-sense --lib` — count matches the 9
205+
promoted files' tests.
206+
- [ ] **T4.3** `cargo check -p katgpt-core` clean (default + all-features).
207+
- [ ] **T4.4** `cargo test -p katgpt-core --lib` — default count delta
208+
matches promoted test count; all-features count delta matches
209+
promoted-with-feature-gate test count.
210+
- [ ] **T4.5** `cargo check -p katgpt-core --features spectral_threat` clean
211+
(this feature now activates `sense_threat` mod + the `linoss` dep).
212+
- [ ] **T4.6** `cargo check --workspace --all-features` clean.
213+
- [ ] **T4.7** `cargo check -p riir-engine` clean (verifies re-export shims
214+
preserve API). **Allow 7-10 min for this step.**
215+
- [ ] **T4.8** `cargo check -p riir-neuron-db --all-features` clean.
216+
- [ ] **T4.9** `cargo check -p riir-chain --all-features` clean.
217+
218+
### Phase 5 — Issue 007 closure
219+
220+
- [ ] **T5.1** Mark Phase E Tier 2 #7 as `[x]` in
221+
`riir-ai/.issues/007_*.md`.
222+
- [ ] **T5.2** Update Tier 2 status summary (now 4/4 done).
223+
- [ ] **T5.3** Update the cumulative Phase E LOC count.
224+
225+
---
226+
227+
## Risks
228+
229+
| Risk | Likelihood | Mitigation |
230+
|---|---|---|
231+
| `ScaleBoundary` has hidden impls / trait bounds that don't fit katgpt-types | Low | It's a POD with derives only; audit in T1.1 |
232+
| `TemporalDerivativeKernel` constructor depends on katgpt-core internals | Medium | T2.1 audit; if so, the constructor stays in katgpt-core and the struct moves |
233+
| `sense/spectral_threat.rs` is consumed externally via `katgpt_core::sense::spectral_threat` | Low | Grep `riir-ai` for the path; if found, re-export through the alias |
234+
| `spectral_threat` Cargo feature and `sense_composition` Cargo feature get tangled | Medium | Audit Cargo.toml feature deps in T3.6 before changing |
235+
| Test count delta doesn't match expected | Low | Established pattern from Tier 1/2 #4-6 works; delta tracking is mechanical |
236+
237+
---
238+
239+
## GOAT Gate (Promotion Criteria)
240+
241+
Per `katgpt-rs/AGENTS.md` Feature Flag Discipline:
242+
243+
1. **G1 correctness**: all promoted tests pass standalone in katgpt-sense.
244+
2. **G2 perf**: not applicable (substrate move, no algorithm change).
245+
3. **G3 no-regression**: katgpt-core test count deltas match exactly; riir-engine
246+
builds unchanged.
247+
4. **G4 alloc-free**: not applicable (no hot-loop changes).
248+
5. **Modelless gain**: ✅ — this is a pure structural refactor with no training
249+
dependency. Promotes to default-on if `sense_composition` was already
250+
default-on (audit in T3.6).
251+
252+
---
253+
254+
## Open Questions to Resolve Before Phase 1
255+
256+
- [ ] Is `sense_composition` currently in katgpt-core's `default` feature list?
257+
(Determines whether katgpt-sense gets default-on status.)
258+
- [ ] Does `sense/spectral_threat.rs` get consumed externally via the
259+
`katgpt_core::sense::spectral_threat` path? If yes, the re-export alias
260+
needs to surface it.
261+
- [ ] Are there other Cargo features that imply `sense_composition`?
262+
(Mirrors how `committed_field_blend` implies `personality_composition`.)
263+
264+
---
265+
266+
## Cross-Repo Coordination
267+
268+
Single-repo change (katgpt-rs only). Sense has no `riir-ai` consumers per
269+
grep (the NPC-runtime half moved in Phase C). Path deps unchanged.
270+
271+
Commit prefix: `feat(katgpt-sense)!: promote sense substrate` for Phase 3,
272+
`feat(katgpt-types): co-extract ScaleBoundary + TemporalDerivativeKernel`
273+
for Phase 1+2.

0 commit comments

Comments
 (0)