本文へ移動
cccskills
無料GitHub で公開

grafema-test-backend-usage

Fix node query issues in Grafema tests when nodes have numeric IDs instead of human-readable IDs, or when `type` field is undefined. Use when: (1) queryNodes returns nodes with numeric IDs like "52710336597754872375318185843222727675" instead of semantic IDs like "net:request#__network__", (2) node.type is undefined but node.nodeType has a value, (3) metadata is a JSON string instead of parsed object, (4) tests fail with "Cannot read property 'length' of undefined" after queryNodes. Covers RFDBServerBackend vs RFDBClient distinction and async generator handling.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md4.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Grafema Test Backend Usage

Problem

Tests querying the graph return malformed node data:

  • IDs are internal numeric strings instead of human-readable semantic IDs
  • type field is undefined (only nodeType is set)
  • metadata is a raw JSON string instead of parsed object
  • originalId and other metadata fields are missing from node

Context / Trigger Conditions

  1. Test uses backend.client to query nodes:

    const graph = backend.client;  // WRONG
    const nodes = await collectNodes(graph.queryNodes({ type: 'net:request' }));
    
  2. Node ID is numeric instead of semantic:

    Expected: "net:request#__network__"
    Actual: "52710336597754872375318185843222727675"
    
  3. node.type is undefined but node.nodeType has the correct value

  4. Using await graph.queryNodes() expecting an array (it's an async generator)

Solution

Issue 1: Use backend directly, not backend.client

// WRONG - returns unparsed wire format
const graph = backend.client;

// CORRECT - returns parsed nodes with human-readable IDs
const graph = backend;

Why: backend is RFDBServerBackend which has _parseNode() that:

  • Extracts originalId from metadata and uses it as the node's id
  • Sets both type and nodeType from wire format
  • Parses and spreads metadata fields onto the node object

backend.client is the raw RFDBClient which returns the wire format without parsing.

Issue 2: Handle async generator properly

// WRONG - queryNodes returns async generator, not Promise<array>
const nodes = await graph.queryNodes({ type: 'net:request' });
nodes.length;  // undefined - nodes is an async generator

// CORRECT - collect results into array
async function collectNodes(asyncGen) {
  const results = [];
  for await (const node of asyncGen) {
    results.push(node);
  }
  return results;
}

const nodes = await collectNodes(graph.queryNodes({ type: 'net:request' }));
nodes.length;  // works correctly

Issue 3: Use correct edge query methods

// WRONG - queryEdges doesn't exist
const edges = await graph.queryEdges({ type: 'CALLS', src: nodeId });

// CORRECT - use getOutgoingEdges or getIncomingEdges
const edges = await graph.getOutgoingEdges(nodeId, ['CALLS']);

Verification

After fixing, verify nodes have correct structure:

for await (const node of backend.queryNodes({ type: 'net:request' })) {
  console.log('ID:', node.id);           // Should be "net:request#__network__"
  console.log('type:', node.type);       // Should be "net:request"
  console.log('nodeType:', node.nodeType); // Should be "net:request"
  console.log('originalId:', node.originalId); // Should match id
}

Example

Full test pattern:

import { createTestBackend } from '../helpers/TestRFDB.js';

describe('My Test', () => {
  let backend;

  beforeEach(async () => {
    backend = createTestBackend();
    await backend.connect();  // Don't forget this!
  });

  afterEach(async () => {
    if (backend) await backend.close();
  });

  it('should find nodes correctly', async () => {
    // ... setup and analysis ...

    // Use backend directly, not backend.client
    const graph = backend;

    // Collect async generator results
    const nodes = [];
    for await (const node of graph.queryNodes({ type: 'net:request' })) {
      nodes.push(node);
    }

    // Now nodes is an array with properly parsed nodes
    assert.strictEqual(nodes[0].id, 'net:request#__network__');
    assert.strictEqual(nodes[0].type, 'net:request');
  });
});

Notes

  • RFDBServerBackend._parseNode() is responsible for the transformation
  • The originalId is stored in the node's metadata JSON field in the database
  • Both type and nodeType are set to the same value after parsing
  • Edge methods (getOutgoingEdges, getIncomingEdges) return arrays, not generators
  • Always call backend.connect() in beforeEach - the backend is not auto-connected

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Fix Elixir/Erlang AST processing bugs in Grafema beam-analyzer. Use when: (1) Elixir parser returns MODULE node but 0 functions/calls — body nesting issue, (2) Erlang parser crashes with "cannot convert list to string" on OTP 26+ — location format changed from integer to keyword list, (3) pipe operator |> creates spurious CALL nodes instead of desugared function calls — clause ordering bug, (4) multi-module .ex files return only the first module — missing __block__ handler, (5) installing Erlang/Elixir on macOS with outdated Xcode/Clang.

日本語の概要は準備中です。原文の説明を表示しています。

Disentinel/grafema362026年8月24日 更新

Fires after fixing any non-trivial bug or regression. Asks: could the graph have caught this as a guarantee? Pairs with reflection-in-and-on-action — picks up after "earliest catchable signal" and asks the next question: was that signal expressible in graph? Triggers: (1) after any non-trivial bug fix is verified working, (2) after a regression report (something used to work, broke), (3) during step 6 (knowledge extraction) of the workflow, (4) when reflection-on-action surfaces a "would have been catchable" signal. Outcome is a triage decision (graph-reachable? rule expressible? rule sound?) and either a draft Linear issue + guarantee proposal, or a recorded "graph capability gap" note. Never auto-creates guarantees.

日本語の概要は準備中です。原文の説明を表示しています。

Disentinel/grafema362026年8月24日 更新

Fix Playwright automation failures against code-server (VS Code in browser). Use when: (1) trust dialog blocks all clicks — "monaco-dialog-modal-block intercepts pointer events", (2) button:has-text() finds wrong buttons behind modal dialog, (3) keyboard shortcuts don't work — Meta vs Control inconsistency, (4) VS Code extension activity bar icon not found by aria-label, (5) panels show placeholder text despite extension being "Connected". Covers trust dialog dismissal, keyboard shortcut hybrid mode, extension panel selectors, and database connection verification for Grafema extension.

日本語の概要は準備中です。原文の説明を表示しています。

Disentinel/grafema362026年8月24日 更新

Systematic methodology for achieving 100% backward dataflow reachability in a new language. Create gauntlet fixture, write trace, diagnose gaps, fix analyzer/algorithm, iterate to 100%. Language-agnostic process. Use when: (1) adding a new language to Grafema, (2) auditing dataflow coverage for existing language, (3) user says "/dataflow-gauntlet".

日本語の概要は準備中です。原文の説明を表示しています。

Disentinel/grafema362026年8月24日 更新

Fix docker exec hanging when starting background processes (servers, daemons) inside containers. Use when: (1) docker exec never returns despite using & or nohup, (2) background server started in container causes docker exec to hang indefinitely, (3) env_startup_command in SWE-bench or similar frameworks times out, (4) setsid/disown needed for proper process detachment in Docker. Root cause: docker exec tracks ALL processes in the exec session, not just the top-level PID.

日本語の概要は準備中です。原文の説明を表示しています。

Disentinel/grafema362026年8月24日 更新

Fix Node.js CLI tools crashing inside Docker containers when host-installed node_modules require a newer Node version than the container provides. Use when: (1) "SyntaxError: Invalid regular expression flags" with /v flag in string-width or similar packages, (2) node_modules installed on host with Node 20+ but container has Node 18, (3) `npm install` with file: protocol creates symlinks that break inside Docker, (4) pnpm workspace packages become broken symlinks in containers. Covers version detection, Node binary mounting, and npm install strategies for cross-version compatibility.

日本語の概要は準備中です。原文の説明を表示しています。

Disentinel/grafema362026年8月24日 更新

Disentinel のスキルをすべて見る

このスキルの問題を報告する