Skip to main content

Known Issues

Internal Document

This page tracks unresolved issues identified in code reviews and audits. It is intended for contributors and maintainers, not end users.

Sources: PLUGIN_SYSTEM_AUDIT.md (2026-02-01), review_overview_feb13.md (2026-02-14), CORE_PLUGIN_INTEGRATION_AUDIT.md (2026-02-04)


Critical Risk​

1. Alias command protocol mismatch vs handler selection​

Rating: Critical | File: src/core/command-registry.ts, src/core/commands.ts, src/components/cli.tsx

CommandRegistry.ρ returns resolved.protocol for G_alias commands based on preference/active context, not on the protocol that the alias command ultimately executes. Alias commands then perform their own fallback protocol search and may run a different protocol command internally. The CLI handler dispatch depends on resolved.protocol + resolved.command.id, so the wrong handler can be selected — or no handler runs for a request payload that requires one.

Risk: Incorrect signing flows, wrong chain assumptions, silent execution failures.

Fix: Normalize the alias execution contract — the resolver should return the actual selected protocol, or alias commands should return protocol metadata consumed by the dispatch layer.


2. lifi:execute produces payload but has no handler​

Rating: Critical | File: src/plugins/lifi/commands.ts:474-529, src/plugins/lifi/handlers.ts:229-230

The execute command returns a lifiTransferRequest payload, but the LiFi handler registry only maps bridge. The CLI dispatch looks up handlers by command ID, so execute cannot complete the transaction flow even when cached quote/route state exists.

Workaround: Use bridge directly for the full LiFi flow.

Fix: Map execute to a handler, or merge execute semantics into bridge.


High Risk​

3. Plugin lifecycle is global while execution contexts are per-tab​

Rating: High | File: src/plugins/plugin-loader.ts, src/components/cli.tsx

Tabs create independent ExecutionContext objects, but the plugin loader is a global singleton and fibers are registered into the global command registry. New tabs repeatedly call loadPlugin() into the same loader without guarding for already-loaded plugins, causing repeated initialization and potential overwrites of the same registry entries.

Risk: Tab isolation is partial. Lifecycle semantics are ambiguous (per-tab state, global plugin/fiber registry).

Fix: Decide and enforce one lifecycle boundary — either per-tab loader+registry or global loader with explicitly shared semantics.


4. Handler path bypasses ExecutionContext.history updates​

Rating: High | File: src/components/cli.tsx

The non-handler path updates context via updateExecutionContext(). The handler path returns early before this update. As a result, ExecutionContext.history and the terminal-rendered history can diverge.

Risk: The history G_core command shows incomplete history. Pipeline DSL (planned) depends on complete history.

Fix: Ensure handler path calls updateExecutionContext consistently after execution.


5. Namespaced alias (protocol:s) shadowed by global alias resolution​

Rating: High | File: src/core/command-registry.ts:152, 189, src/core/commands.ts:741-746

Alias map lookup runs before namespace parsing. registerCoreCommands() adds a global s → swap alias which can intercept the user's intent for a namespaced alias. Behavior differs from intended explicit namespace semantics.


Medium Risk​

6. Plugin unload does not deregister commands​

Rating: Medium | File: src/plugins/plugin-loader.ts:129-134

unloadPlugin removes the plugin entry but does not deregister fiber commands. After "unloading", the command registry still resolves the plugin's commands.

Risk: False sense of removal. Useful for dynamic plugin reloading or plugin security isolation.


7. Hybrid core/plugin model for CoinPaprika and Faucet​

Rating: Medium | File: src/plugins/coinpaprika/index.ts, src/plugins/faucet/index.ts, src/core/commands.ts

Core imports commands directly from the CoinPaprika and Faucet plugin folders. These commands have scope: 'G_core' but are also attempted as plugin fiber commands. This breaks the scope invariant and would throw at runtime if these plugins are ever loaded as true protocol plugins.

Risk: These features are not truly plugin-modular; they are effectively core utilities stored under plugins/.

Fix: Choose one model — either promote to core-only utilities and remove the plugin registration, or keep as proper plugins with G_p scope and optional G_core aliases.


8. Test/typecheck pipeline is not wired​

Rating: Medium | File: src/core/__tests__/alias-resolution.test.ts, src/core/monoid.test.ts

pnpm exec tsc --noEmit fails due to missing test runner globals/types. Static typecheck cannot be used as a reliable CI gate in the current repo state.

Fix: Add/align test runner config (vitest/jest) and isolate test tsconfig.


Low Risk​

9. Excessive debug logging in critical runtime paths​

Rating: Low | File: src/components/cli.tsx:422, 428, 661, 1142

Frequent console.log calls in CLI/tab lifecycle and command flow. Produces noisy logs, makes debugging harder, and potentially leaks runtime context (wallet state, protocol selection, tab names) in production.

Fix: Guard all logging behind process.env.NODE_ENV === 'development' and use structured logging.


10. Dual registration of CoinPaprika/Faucet commands​

Rating: Low | File: src/plugins/coinpaprika/commands.ts, src/plugins/faucet/commands.ts

These commands have scope: 'G_core' but are also passed to addCommandToFiber in the plugin's initialize(). The fiber validator will throw if these plugins are ever loaded as standard protocol plugins.


Recommendations​

PriorityFix
1Normalize alias execution contract (Critical #1)
2Fix LiFi execute handler binding (Critical #2)
3Enforce one plugin lifecycle boundary (High #3)
4Ensure handler path updates history (High #4)
5Resolve core-vs-plugin boundary for CoinPaprika/Faucet (Medium #7)
6Fix test runner config and typecheck pipeline (Medium #8)