AIDE Trace Intelligence (GhostCode Integration)
SkillDev toolsAIDE Trace Intelligence, the sovereign runtime-trace subsystem (Observe → Trace → Map → Replay → Explain → Fix → Verify) that makes GhostCode's product promise real. Research-grounded on the Node.js V8 inspector / Chrome DevTools Protocol (CDP). Use whenever implementing, extending, testing, or auditing trace-engine.ts, routes/trace.ts, the trace contract, the 'trace' WS channel, the RA 'Analyze Trace' hook, or when feeding runtime-failure evidence into agent prompts or Veritas.
Use AIDE Trace Intelligence (GhostCode Integration) in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add AIDE Trace Intelligence (GhostCode Integration) and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the AIDE Trace Intelligence (GhostCode Integration) skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by anonymousnomad/covert-coder in skills/packs/aide-trace-intelligence/SKILL.md and read by Ahel’s review.
1. North Star & Boundaries
What this is: a sovereign, offline runtime-trace subsystem. A child Node program runs under the built-in V8 inspector; we consume the Chrome DevTools Protocol (CDP) over WebSocket to capture execution events, map them to source, and emit a correlation-aware failure evidence chain for the Resident Assistant / primary model / Veritas.
Who collaborates in AIDE: the community works on this repo. This skill is the canonical build spec — read it before touching any trace file.
Sovereignty (R9): zero cloud, zero external runtime libraries. The tracer uses process.execPath (the same Node the daemon runs on). GhostCode's submitted repo declared MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API — that capability MUST NOT be imported into AIDE.
Replay honesty contract: replay = stepping through captured events on a timeline. It is NOT byte-level time travel, and it is never overpromised. Capability detection reports exactly what the engine can do.
Scope guardrails (verified project law): Trace Intelligence is an ADDITIVE subsystem. Never modify: the editor, daemon core, model runtime, the existing DAP/LSP managers, scripts/start.mjs, or the facade topology (port 4777 single edge).
2. Verified Research Base (sources on record)
These facts are confirmed, not assumed. If behavior contradicts them, the code is wrong, not the protocol.
- Attach mechanics (nodejs.org debugger docs + node core issue #24085):
node --inspect/--inspect-brkprintsDebugger listening on ws://127.0.0.1:PORT/UUIDon stderr.--inspect-port=0(or--inspect-brk=127.0.0.1:0) requests a random, race-free port; parse the actual ws URL out of stderr. (bnoordhuis, node core: "You can start the inspector race free on a random port with --inspect-port=0.") - Security (node cli docs, "debugging security implications"): binding the inspector to a public IP is insecure — remote code execution attack via the debugger WS. Default host is 127.0.0.1. Always bind explicit loopback:
--inspect-brk=127.0.0.1:0. --inspect-brkvs--inspectvs--inspect-wait: brk breaks on the first line of user code as soon as the debugger attaches; wait pauses until Runtime.runIfWaitingForDebugger. We use brk + attach +Runtime.runIfWaitingForDebugger.--enable-source-maps(node cli docs): makes stack traces report original source lines (TS/etc.) instead of transpiled output. Caveat: a customError.prepareStackTracein the traced program prevents the rewrite (node issue #29994, #50733). Also small overhead on everyError.stackaccess — fine for a trace target.- CDP structures (chromedevtools.github.io/devtools-protocol/*/Runtime):
Runtime.enable→ sendsexecutionContextCreatedimmediately for EVERY existing context (so with brk, the main context event arrives on attach, not before).Runtime.consoleAPICalledparams:type(log|debug|info|error|warning|dir|dirxml|table|trace|clear|startGroup|startGroupCollapsed|endGroup|assert|profile|profileEnd|count|timeEnd),args: RemoteObject[],executionContextId,timestamp,stackTrace(async chain auto-reported only for assert/error/trace/warning),context.Runtime.exceptionThrownparams:timestamp,exceptionDetails: { exceptionId, text, lineNumber (0-based), columnNumber (0-based), scriptId, url, stackTrace: { description, callFrames: [CallFrame], parent, parentId }, exception: RemoteObject }.Runtime.StackTrace.callFrames[]→Runtime.CallFrame:{ functionName, scriptId, url, lineNumber (0-based), columnNumber (0-based) }.Debugger.scriptParsedparams:scriptId, url, startLine, startColumn, endLine, endColumn, executionContextId, hash, isModule, hasSourceURL, sourceMapURL, ....- 0-based vs 1-based: CDP line/column numbers are 0-based; editors/markers/tests are 1-based. Convert by +1 at the capture boundary — do it in ONE place (the mapper), not scattered.
Runtime.CallFrame.urlfornode:internal/*andevalframes is NOT a file path — filter those out so the trace only surfaces workspace/user code.RemoteObject:{ type, subtype, className, value, unserializableValue (NaN/Infinity/-Infinity/-0/BigInt), description, objectId }. Primitivevaluestrings can be huge — cap them. Objects carrydescription(usually truncated by the runtime) — prefer that over evaluatingobjectId(avoid property walks unless a UI feature demands them).
- Memory discipline (node inspector docs + CDP): "Original objects are maintained in memory unless they are either explicitly released or are released along with the object group." The inspector console keeps console-argument objects alive. For a short-lived trace target (seconds) this is irrelevant; for a long-lived target add periodic
Runtime.discardConsoleEntries(and drop stored entries), else the traced process grows.Runtime.discardConsoleEntriesonly clears the inspector's own console store, not our stored events.
- WebSocket client (project dependency):
wsis already a dependency (events.ts imports{ WebSocket, WebSocketServer }).new WebSocket(url)is the client. No new dependency is required. The Node inspector WS server does not require a special subprotocol.
3. Architecture Map (as implemented)
common/contracts/trace.ts— zod.strict()contract:TraceCapabilities,TraceEvent(id/ts/kind/runtime/detail/file/line/column/callStack/value/errorMessage),TraceSession,TraceSessionDetail(summary +events),TraceStartRequest/Response,TraceStatusResponse,TraceStopResponse,TraceListResponse,TraceQuery/TraceSessionResponse,TraceEvidence(failure/immediate_cause/previous_state_transitions/originating_value/relevant_input/confidence/caveat),TraceEvidenceResponse,TraceStreamEvent(WS payload). TypesTrace*Texported for both TS stacks.node/src/services/trace-engine.ts—TraceEngineclass. spawn → stderr ws-URL parse → WebSocket attach →Runtime.enable+Debugger.enable+Runtime.runIfWaitingForDebugger→ event capture → source mapping → evidence chain builder. Capability probe vianode --version. Session store in-memory (Map + ordered array). Max events (10000) + max sessions (20) with eviction.node/src/routes/trace.ts—routesForTrace(engine): GET/api/trace/status, POST/api/trace/start, POST/api/trace/stop, GET/api/trace/list, GET/api/trace?id=…, GET/api/trace/evidence?id=….- Wired in
node/src/openapi.ts:BuildRoutesOptions.traceEngine?: TraceEngine; created inmain()(node/src/server.ts) and passed in WITH a shutdown hookserver.addShutdownHook(() => traceEngine.shutdownAll())— same pattern as dapManager. Fallbacknew TraceEngine({...})insidebuildRoutesfor tests. node/src/events.ts—tracechannel added (schemaTraceStreamEvent); engine publishes{sessionId, event}live.common/facade-route-map.json—/api/trace→"ts".common/openapi.json— regenerated vianode scripts/contracts.mjs.- RA hook: resident views the last failed trace via
/api/trace/evidence?id=<last>(id of last session with exceptionCount>0 or exitCode!==0) and surfaces "Analyze Trace".
4. What To Do / How (build sequence)
- Contract first (
common/contracts/trace.ts): all request/response schemas.strict(), description strings capped (see traps), replay mode literal'timeline'. - Engine (
node/src/services/trace-engine.ts): the exact flow that works (verified against research):caps = await capabilities(); throw if node probe false.- Resolve
cwd/targetinside workspace (path containment — hold the boundary). - Spawn
process.execPath(ornodeCommandoverride) with['--inspect-brk=127.0.0.1:0', '--enable-source-maps', target, ...args],stdio: ['ignore','pipe','pipe'],windowsHide: true, env{...process.env, AIDE_TRACE_SESSION: id}. - On stderr data: tee into output events AND regex
/ws:\/\/[^\s]+/for the ws URL. On stdout data: output events. waitForReady: poll for ws URL / error status / child-exit promise flag up to 15s.connect:new WebSocket(wsUrl); on open sendRuntime.enable,Debugger.enable,Runtime.runIfWaitingForDebugger; set statusrunning. Resolve start() only after open succeeds so the response reflects a real attach.- In
handleMessage, switch onmessage.methodfor the four capture cases + ignore the rest. - On child
exit,finalize(exitCode, status, error if nonzero w/o exception, publish exit event, close socket). - Evidence builder: locate last exception event; slice the ≤10 prior console/script events; build
TraceEvidencewith explicitconfidence(see §7 correlation law) and caveat text.
- Routes (
node/src/routes/trace.ts): thin, throwRouteError('NOT_FOUND', …)for unknown sessions so the server maps to 404 (not 500),RouteError('BAD_REQUEST', …)for bad input. - Wiring: openapi.ts option + fallback;
main()construction + shutdown hook; events channel; facade map"/api/trace": "ts"; regenerate openapi.json. - Tests (
tests/arch/trace-routes.test.tsetc., ArchServer + mkdtemp-workspace style): capability detection honesty, contract validation, REAL spawn of a tiny workspace script that logs twice then throws → assert script/console/exception events, source mapping (file resolves inside workspace, line is 1-based), evidence non-null with confidence, HTTP 404 on unknown id, facade map present,/api/trace/statuscaps. Also assertnode:internalframes are filtered. - Gates:
tsc -p tsconfig.node.json, eslint,node scripts/contracts.mjs, focused arch tests, then broader battery (CI is the real gate on Windows for the pre-existing 5 local failures).
5. What Code To Write — key patterns (do not hand-wave)
// engine — spawn + stderr url parse
const wsUrlMatch = /ws:\/\/[^\s]+/.exec(text); // from stderr 'data'
// attach — MUST enable before runIfWaitingForDebugger
this.send(socket, 'Runtime.enable', {});
this.send(socket, 'Debugger.enable', {});
this.send(socket, 'Runtime.runIfWaitingForDebugger', {});
// mapper — single place converting CDP -> editor coordinates
function mapFile(url: string | undefined): string | null {
if (!url) return null;
if (url.startsWith('file://')) return path.resolve(decodeURIComponent(url.slice(7)));
if (url.startsWith('/') || /^[A-Za-z]:[\\/]/.test(url)) return path.resolve(url);
return null; // node:internal, eval, http — filtered
}
const LINE = (n?: number) => (typeof n === 'number' && n >= 0 ? n + 1 : 0); // CDP 0-based -> 1-based
// value capture — shallow, capped
function stringifyRemote(o: CdpRemote | undefined): string {
if (!o) return '';
if (o.unserializableValue) return truncate(o.unserializableValue, 500);
if (o.type === 'string') return truncate(String(o.value ?? ''), 500);
if (o.value !== undefined) return truncate(String(o.value), 500);
if (o.description) return truncate(o.description, 500);
return `[${o.type ?? 'remote'}]`;
}
Never store objectId; never call Runtime.getProperties in v0 (keeps the size bounded and no retained-object graph).
6. What NOT To Do (hard rules)
- Do NOT bind the inspector to anything but loopback.
0.0.0.0is an RCE vector. - Do NOT use a fixed port (9229 or manual slot assignment) — race with the operator's llama-server (8081, PID 11740 — never touch) and other tools; use port 0 + stderr parse.
- Do NOT hardcode
nodefrom PATH — useprocess.execPath; PATH node may differ from the daemon's node. - Do NOT claim byte-level replay. Capability says
replay: 'timeline'. UI says "step captured events". - Do NOT claim causation. Evidence is correlation with explicit confidence + caveat (§7).
- Do NOT eval/執行 arbitrary target-side expressions; never
Runtime.evaluateuser text. - Do NOT capture beyond caps (10000 events) or store unbounded strings; truncate at every field.
- Do NOT let a traced child outlive the daemon: shutdown hook must kill active sessions.
- Do NOT return
INTERNAL(500) for unknown session ids —RouteError('NOT_FOUND'). - Do NOT modify editor/daemon-core/DAP/LSP/model code to make traces work.
- Do NOT copy GhostCode source or its Gemini capability into AIDE.
7. Issues + Dependency Registry
- Correlation ≠ causation (the honesty law). Failure evidence chains ordering into
previous_state_transitions, but the top of the chain is the closest PRIOR event, not proof of cause. confidence rules:high= failure source-mapped AND immediate_cause in same file;medium= source-mapped but cause elsewhere/none;low= no source resolution. Caveat text is part of the contract — never drop it. Runtime.enablefiresexecutionContextCreatedfor existing contexts immediately. With brk, the main context appears right after attach — expect one context event even in an empty script.node:internal/*frames: url is not file:// — the mapper must filter them or the timeline fills with framework noise.- Async stack traces auto-report only for assert/error/trace/warning (CDP). Other
console.*calls lose the async chain unlessDebugger.getStackTraceis called withparentId— out of scope for v0. - Dependencies:
ws(already in repo, used by events.ts) — no new deps. zod (present).tsc/eslint (present).mkdtemp+ node:test for tests. - Remaining v0 gaps (say them out loud, don't hide): long-lived-target memory (add
Runtime.discardConsoleEntriesloop); no source .map decode of our own (we rely on--enable-source-maps); sessions in-memory only (daemon restart loses them); RA link is via last-session id not a subscription;TraceStreamEventWS channel is publish-only (no filtering by session).
8. Known Bugs & Traps (verified in this codebase)
- Windows
AddShutdownHook/spawn cleanup: always close the child AND the ws socket; a killed child'sexitevent may still fire after kill → guard withstoppedByUserso status staysstopped, and null the socket inclose. - stderr stdout buffering: never concatenate unbounded stderr — keep a capped tail (4000 chars) for the error message fallback.
- Port-0 + pipe: do NOT parse stdout for the ws URL (node writes it to stderr); a wrapped launcher may reprint it — only match the first occurrence on stderr.
--enable-source-maps+ customError.prepareStackTrace: some libs break the rewrite; if a frame stays on the generated file, that is the target's own code overriding behavior — the engine'ssource_mappingcapability must stay honest (it reports true only because we pass the flag; a target that breaks it is its own fault, documented, not our bug).- Double exit event:
finalizepublishes the exit event; do NOT publish another one instart()afterwaitForReady. structuredClone(detail)before returning: handlers must never mutate live session state.- Agent memory: don't leave spawned trace children running after a test — the test battery asserts process hygiene; kill in
after(). - Contract regeneration: after touching
common/contracts/trace.ts, runnode scripts/contracts.mjsand commitcommon/openapi.jsondrift; verify zod==lockfile before regen.
9. Threat Matrix
| Threat | Vector | Mitigation (this code) |
|---|---|---|
| Inspector RCE | traced process exposes inspector on public interface | loopback-only bind (--inspect-brk=127.0.0.1:0) |
| Inspector RCE via hostile workspace script | arbitrary Runtime.evaluate from the tracer | tracer never evaluates; reads events only |
| Path escape | target/cwd resolves outside workspace | path.relative containment check at start |
| DoS / memory exhaustion | unbounded event/value capture | caps: 10000 events, string caps per field, session eviction (20) |
| Child process leak | orphan inspector children | shutdown hook → shutdownAll(); stoppedByUser guard; test battery process hygiene |
| Info disclosure | console args containing secrets | values capped to 500 chars shallow preview; store is local/in-process, .aide not synced |
| WS channel abuse | subscriber floods / replay | channel is server-published only; client subscribes per channel; schema-validated payloads |
| Supply chain in trace target | target requires malicious deps | the user runs the workspace code; tracer only observes (same privilege as node the user already runs) |
| False causality in AI evidence | evidence chain misread as cause | explicit confidence + caveat in TraceEvidence; RA wording must say "closest prior event" |
10. Verification Battery (before claiming done)
node scripts/contracts.mjssucceeds andcommon/openapi.jsonregenerates.tsc -p tsconfig.node.jsonand eslint pass.- Arch tests: focused
tests/arch/trace-*.test.ts(real spawn, source mapping, evidence, 404s, caps, facade map) then the broader battery; CI green is the authoritative gate. - Manual: start a real trace of a failing script via
POST /api/trace/start, observeexceptionCount>=1,GET /api/trace/evidence?id=…returns non-null,node:internalframes absent. - Process hygiene: no stray
node --inspect-brkprocesses remain (Get-Process nodematches pre-test baseline). - Journal
AGENT_NOTES.mdwith what changed + this subsystem's state.
11. Future Runtimes (design ready, not built)
The evidence contract is runtime-agnostic (TraceRuntime enum, runtime: 'node'). To add Python later: spawn with a debugger (debugpy) speaking the SAME CDP-ish protocol is wrong — instead define a normalized emitter: the runtime emits structured AIDE_TRACE_* events (env contract AIDE_TRACE_SESSION already exists), and the engine maps that emitter's output into TraceEvent. Never bolt a second protocol parser in; normalize at the edge.
Signals
- GitHub stars
- 43
- Forks
- 14
- Last commit
- Oct 2026
Advanced
- Item type
- skill
- Key
aide-trace-intelligence- Source
- github.com/anonymousnomad/covert-coder
github.com/anonymousnomad/covert-coder
Related picks
Skill · thedaviddias
The pick for JavaScriptmodern-javascript-patterns
Skill · wshobson
The pick for JavaScriptsetup-ts-deep-modules
Skill · mattpocock
The pick for TypeScripttypescript-pro
Skill · jeffallan
The pick for TypeScriptpython-performance-optimization
Skill · wshobson
The pick for Pythonpython-pro
Skill · jeffallan
The pick for Python