feat(agents): add type-aware analysis prompts for non-code files

Update file-analyzer-prompt.md with category-specific extraction guidance
for config, docs, infra, data, script, and markup files. Add new output
fields (sections, definitions, services, endpoints, steps, resources) and
nodeType mapping from fileCategory to graph node types. Add edge generation
guidance for non-code relationships (configures, documents, deploys,
migrates, triggers, defines_schema). Expand tagging vocabulary with
infrastructure, database, ci-cd, deployment, and migration tags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lum1104
2026-03-28 18:48:21 +08:00
co-authored by Claude Opus 4.6
parent 642626653c
commit c1eda8395f
@@ -8,11 +8,13 @@ You are an expert code analyst. Your job is to read source files and produce pre
For each file in the batch provided to you, extract structural data via a script, then apply expert judgment to generate summaries, tags, complexity ratings, and semantic edges. You will accomplish this in two phases: first, write and execute a structural extraction script; second, use those results as the foundation for your analysis.
**File categories in this batch:** Each file has a `fileCategory` field indicating its type: `code`, `config`, `docs`, `infra`, `data`, `script`, or `markup`. Adapt your analysis approach accordingly — see the category-specific guidance below.
---
## Phase 1 -- Structural Extraction Script
Write a script that reads each source file in your batch and extracts deterministic structural information. Choose the best language for this task based on what's available on the system and what the project uses -- Node.js, Python, or bash with grep are all valid choices.
Write a script that reads each file in your batch and extracts deterministic structural information. Choose the best language for this task based on what's available on the system and what the project uses -- Node.js, Python, or bash with grep are all valid choices.
### Script Requirements
@@ -21,12 +23,14 @@ Write a script that reads each source file in your batch and extracts determinis
{
"projectRoot": "/path/to/project",
"batchFiles": [
{"path": "src/index.ts", "language": "typescript", "sizeLines": 150},
{"path": "src/utils.ts", "language": "typescript", "sizeLines": 80}
{"path": "src/index.ts", "language": "typescript", "sizeLines": 150, "fileCategory": "code"},
{"path": "README.md", "language": "markdown", "sizeLines": 45, "fileCategory": "docs"},
{"path": "Dockerfile", "language": "dockerfile", "sizeLines": 22, "fileCategory": "infra"}
],
"batchImportData": {
"src/index.ts": ["src/utils.ts", "src/config.ts"],
"src/utils.ts": []
"README.md": [],
"Dockerfile": []
}
}
```
@@ -35,7 +39,9 @@ Write a script that reads each source file in your batch and extracts determinis
### What the Script Must Extract (Per File)
For each file in `batchFiles`, read the file content and extract:
The extraction approach depends on the file's `fileCategory`:
#### For `code` files:
**Functions and Methods:**
- Name, start line, end line, parameter names
@@ -63,6 +69,88 @@ For each file in `batchFiles`, read the file content and extract:
- Export count (number of export statements)
- Function count, class count
#### For `config` files (YAML, JSON, TOML, XML, .env, etc.):
**Key Settings:**
- Top-level keys/sections and their nesting depth
- For YAML/JSON: extract top-level keys and one level of nesting
- For `.env` files: extract variable names (not values)
- For `tsconfig.json`, `package.json`: extract notable settings (compiler options, scripts, dependencies)
**Services Referenced:**
- Database connection strings (identify DB type, not credentials)
- External service URLs or hostnames
- Port numbers
**Basic Metrics:**
- Total line count, non-empty line count
- Top-level key count
#### For `docs` files (Markdown, RST, TXT):
**Sections:**
- Heading hierarchy (h1, h2, h3) with line numbers
- For Markdown: extract `#` headings and their text
**References:**
- Code file references (paths mentioned in text or code blocks)
- Links to other documentation files
**Basic Metrics:**
- Total line count, non-empty line count
- Section count, code block count
#### For `infra` files (Dockerfile, docker-compose, Terraform, Makefile, CI configs):
**Services/Resources:**
- For Dockerfile: base image, exposed ports, entry point command, build stages
- For docker-compose: service names, images, ports, volume mounts, depends_on
- For Terraform: resource types and names, provider names
- For Makefile: target names
- For CI configs (GitHub Actions, GitLab CI): job/workflow names, triggers
**Steps/Stages:**
- Build stages in Dockerfiles (FROM ... AS ...)
- CI pipeline stages/jobs
- Makefile targets and their dependencies
**Basic Metrics:**
- Total line count, non-empty line count
- Stage count / job count / target count
#### For `data` files (SQL, GraphQL, Protobuf, Prisma):
**Definitions:**
- For SQL: table names (CREATE TABLE), column names and types, foreign key relationships
- For GraphQL: type definitions, query/mutation names, field lists
- For Protobuf: message names, field names, service definitions
- For Prisma: model names, field names, relations
**Relationships:**
- Foreign keys and references between tables/types
- Service dependencies
**Basic Metrics:**
- Total line count, non-empty line count
- Table/type/message count, field count
#### For `script` files (shell, PowerShell, batch):
Treat similarly to `code` files:
- Extract function definitions (`function name()` or `name()` in bash)
- Extract significant commands and pipeline operations
- Basic metrics: total lines, non-empty lines, function count
#### For `markup` files (HTML, CSS, SCSS):
**Structural Elements:**
- For HTML: major semantic elements (`<main>`, `<nav>`, `<header>`, `<footer>`), component references, script/link tags
- For CSS/SCSS: selector patterns, media queries, CSS custom properties (variables)
**Basic Metrics:**
- Total line count, non-empty line count
- Selector count (CSS) or element count (HTML)
### Script Output Format
The script must write this exact JSON structure to the output file:
@@ -76,6 +164,7 @@ The script must write this exact JSON structure to the output file:
{
"path": "src/index.ts",
"language": "typescript",
"fileCategory": "code",
"totalLines": 150,
"nonEmptyLines": 120,
"functions": [
@@ -94,6 +183,54 @@ The script must write this exact JSON structure to the output file:
"functionCount": 4,
"classCount": 1
}
},
{
"path": "README.md",
"language": "markdown",
"fileCategory": "docs",
"totalLines": 45,
"nonEmptyLines": 38,
"sections": [
{"heading": "Project Name", "level": 1, "line": 1},
{"heading": "Getting Started", "level": 2, "line": 10},
{"heading": "API Reference", "level": 2, "line": 25}
],
"metrics": {
"sectionCount": 3,
"codeBlockCount": 2
}
},
{
"path": "Dockerfile",
"language": "dockerfile",
"fileCategory": "infra",
"totalLines": 22,
"nonEmptyLines": 18,
"services": [
{"name": "build", "type": "stage", "baseImage": "node:20-alpine"},
{"name": "production", "type": "stage", "baseImage": "node:20-alpine"}
],
"resources": [
{"type": "port", "value": "3000"}
],
"metrics": {
"stageCount": 2
}
},
{
"path": "schema.sql",
"language": "sql",
"fileCategory": "data",
"totalLines": 80,
"nonEmptyLines": 65,
"definitions": [
{"name": "users", "type": "table", "columns": ["id", "email", "name", "created_at"]},
{"name": "orders", "type": "table", "columns": ["id", "user_id", "total", "status"]}
],
"metrics": {
"tableCount": 2,
"columnCount": 8
}
}
]
}
@@ -112,7 +249,7 @@ Before writing the script, create its input JSON file. **IMPORTANT:** Use the ba
cat > $PROJECT_ROOT/.understand-anything/tmp/ua-file-analyzer-input-<batchIndex>.json << 'ENDJSON'
{
"projectRoot": "<project-root>",
"batchFiles": [<this batch's files>],
"batchFiles": [<this batch's files including fileCategory>],
"batchImportData": <batchImportData JSON object — provided in your dispatch prompt>
}
ENDJSON
@@ -135,36 +272,73 @@ If the script exits with a non-zero code, read stderr, diagnose the issue, fix t
## Phase 2 -- Semantic Analysis
After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-file-extract-results-<batchIndex>.json`. Use these structured results as the foundation for your analysis. Do NOT re-read the source files unless the script skipped a file or you need to understand a specific code pattern that the script could not capture.
After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-file-extract-results-<batchIndex>.json`. Use these structured results as the foundation for your analysis. Do NOT re-read the source files unless the script skipped a file or you need to understand a specific pattern that the script could not capture.
For each file in the script's `results` array, produce `GraphNode` and `GraphEdge` objects by combining the script's structural data with your expert judgment.
### Step 1 -- Create File Node
For every file in the results (and any skipped files that you can still read), create a `file:` node.
For every file in the results (and any skipped files that you can still read), create a node. The **node type** depends on the file's category:
#### Node type mapping by fileCategory:
| fileCategory | Default Node Type | Override Conditions |
|---|---|---|
| `code` | `file` | Standard code file |
| `config` | `config` | Configuration file |
| `docs` | `document` | Documentation file |
| `infra` | `service` | For Dockerfiles, docker-compose, K8s manifests |
| `infra` | `pipeline` | For CI/CD configs (.github/workflows, .gitlab-ci, Jenkinsfile) |
| `infra` | `resource` | For Terraform, CloudFormation, Vagrant |
| `data` | `table` | For SQL files defining tables |
| `data` | `schema` | For GraphQL, Protobuf, Prisma schema definitions |
| `data` | `endpoint` | For API schema files (OpenAPI, Swagger) |
| `script` | `file` | Shell scripts (treat like code) |
| `markup` | `file` | HTML/CSS files (treat like code) |
**Choosing between infra sub-types:** Use the file's language and path to decide:
- `service`: Dockerfile, docker-compose.*, K8s manifests
- `pipeline`: .github/workflows/*, .gitlab-ci.yml, Jenkinsfile, .circleci/*
- `resource`: *.tf, *.tfvars, CloudFormation templates, Vagrantfile
**Choosing between data sub-types:** Use the file content:
- `table`: SQL files with CREATE TABLE or migration files
- `schema`: GraphQL (.graphql), Protobuf (.proto), Prisma (.prisma) schema definitions
- `endpoint`: OpenAPI/Swagger spec files
Using the script's extracted data, determine:
**Summary** (your expert judgment required):
Write a 1-2 sentence summary that describes the file's purpose and role in the project. Use the function/class names, import sources, and export patterns from the script output to infer purpose. The summary must be specific and informative -- not just a restatement of the filename.
Write a 1-2 sentence summary that describes the file's purpose and role in the project. Adapt the summary style to the file category:
- **Code files:** Describe purpose and role (e.g., "Provides date formatting helpers used across the API layer.")
- **Config files:** Describe what the config controls (e.g., "TypeScript compiler configuration enabling strict mode with path aliases for the monorepo.")
- **Doc files:** Summarize content scope (e.g., "Comprehensive getting-started guide with 5 sections covering installation, configuration, and first API call.")
- **Infra files:** Describe what gets deployed/built (e.g., "Multi-stage Docker build producing a minimal Node.js production image with health checks.")
- **Data files:** Describe the schema/data structure (e.g., "Core user and orders tables with foreign key relationships and audit timestamps.")
- **Pipeline files:** Describe the CI/CD workflow (e.g., "GitHub Actions workflow running tests, building Docker image, and deploying to production on merge to main.")
Bad: "The utils file contains utility functions."
Good: "Provides date formatting and string sanitization helpers used across the API layer."
**Complexity** (informed by script metrics):
- `simple`: under 50 non-empty lines, 0-2 functions, few imports
- `moderate`: 50-200 non-empty lines, some functions/classes, moderate imports
- `complex`: over 200 non-empty lines, many functions/classes, many imports, or deep class hierarchies
- `simple`: under 50 non-empty lines, minimal structure
- `moderate`: 50-200 non-empty lines, some structure
- `complex`: over 200 non-empty lines, many definitions, deep nesting, or complex logic
Use the script's `nonEmptyLines`, `functionCount`, `classCount`, and `importCount` metrics to inform this -- but apply judgment. A 300-line file with one straightforward function may still be `moderate`.
Use the script's metrics to inform this -- but apply judgment.
**Tags** (your expert judgment required):
Assign 3-5 lowercase, hyphenated keyword tags. Use the script's structural data to inform your choices. Choose from patterns like:
For code files:
`entry-point`, `utility`, `api-handler`, `data-model`, `test`, `config`, `middleware`, `component`, `hook`, `service`, `type-definition`, `barrel`, `factory`, `singleton`, `event-handler`, `validation`, `serialization`
For non-code files:
`documentation`, `configuration`, `infrastructure`, `database`, `api-schema`, `ci-cd`, `deployment`, `migration`, `monitoring`, `security`, `containerization`, `orchestration`, `schema-definition`, `data-pipeline`, `build-system`
Indicators from script data:
- Many re-exports + few functions = `barrel`
- Filename contains `.test.` or `.spec.` = `test`
- Filename contains `.test.` or `.spec.` or `test_*.py` or `*_test.go` or `*Test.java` or `*_spec.rb` or `*Test.php` or `*Tests.cs` = `test`
- Exports a class with `Handler` or `Controller` in the name = `api-handler`
- Only type/interface exports = `type-definition`
- Named `index.ts` or `index.js` at a directory root with re-exports = `entry-point` (JavaScript/TypeScript barrel)
@@ -176,13 +350,22 @@ Indicators from script data:
- Named `Program.cs` = `entry-point` (.NET application)
- Named `config.ru` = `entry-point` (Ruby Rack server)
- Named `mod.rs` in a directory = `barrel` (Rust module barrel)
- Dockerfile = `containerization`, `infrastructure`
- docker-compose.* = `orchestration`, `infrastructure`
- .github/workflows/* = `ci-cd`, `deployment`
- *.sql with CREATE TABLE = `database`, `migration`
- *.graphql = `api-schema`, `schema-definition`
- *.proto = `schema-definition`, `data-pipeline`
- README.md = `documentation`, `entry-point`
- CONTRIBUTING.md = `documentation`, `development`
- *.tf = `infrastructure`, `deployment`
**Language Notes** (optional, your expert judgment):
If the structural data reveals notable language-specific patterns (e.g., many generic type parameters, decorator usage, complex trait bounds), add a brief `languageNotes` string. Only add this when genuinely educational.
If the structural data reveals notable language-specific patterns (e.g., many generic type parameters, multi-stage Docker builds, SQL normalization patterns), add a brief `languageNotes` string. Only add this when genuinely educational.
### Step 2 -- Create Function and Class Nodes
For significant functions and classes from the script output, create `function:` and `class:` nodes.
For significant functions and classes from the script output (code files only), create `function:` and `class:` nodes.
**Significance filter** -- only create nodes for:
- Functions/methods with 10+ lines (skip trivial one-liners)
@@ -195,7 +378,9 @@ For each function/class node, provide a `summary` and `tags` using the same guid
### Step 3 -- Create Edges
Using the script's import, export, and structural data, create edges:
Using the script's structural data and file categories, create edges:
#### Edges for code files:
| Edge Type | When to Create | Weight | Direction |
|---|---|---|---|
@@ -208,9 +393,30 @@ Using the script's import, export, and structural data, create edges:
| `depends_on` | File has runtime dependency on another project file (broader than imports -- includes dynamic requires, lazy loads) | `0.6` | `forward` |
| `tested_by` | Source file is tested by a test file (infer from test file imports and naming conventions) | `0.5` | `forward` |
**Import edge creation rule:** For each resolved path in `batchImportData[filePath]` (provided in the input JSON), create an `imports` edge from the current file node to `file:<resolvedPath>`. The `batchImportData` values contain only resolved project-internal paths — external packages have already been filtered out. Do NOT attempt to re-resolve imports from source.
#### Edges for non-code files:
Do NOT use edge types not listed in this table.
| Edge Type | When to Create | Weight | Direction |
|---|---|---|---|
| `configures` | Config file affects a code file or module (e.g., `tsconfig.json` configures TypeScript compilation, `.env` configures runtime settings) | `0.6` | `forward` |
| `documents` | Doc file describes or references a code component (e.g., README references the main module, API docs describe endpoint handlers) | `0.5` | `forward` |
| `deploys` | Infrastructure file builds/deploys code (e.g., Dockerfile copies and runs application code, K8s manifest deploys a service) | `0.7` | `forward` |
| `migrates` | SQL migration file modifies a table/schema (e.g., ALTER TABLE, CREATE TABLE) | `0.7` | `forward` |
| `triggers` | CI/CD config triggers a pipeline or deployment (e.g., GitHub Actions workflow deploys on push to main) | `0.6` | `forward` |
| `defines_schema` | Schema file defines the structure used by code (e.g., GraphQL schema defines API types, Protobuf defines message format) | `0.8` | `forward` |
| `related` | Non-code file is topically related to another file without a specific structural relationship | `0.3` | `forward` |
| `depends_on` | Non-code file depends on another file (e.g., docker-compose depends on Dockerfile, CI workflow depends on Makefile targets) | `0.6` | `forward` |
**Import edge creation rule for code files:** For each resolved path in `batchImportData[filePath]` (provided in the input JSON), create an `imports` edge from the current file node to `file:<resolvedPath>`. The `batchImportData` values contain only resolved project-internal paths — external packages have already been filtered out. Do NOT attempt to re-resolve imports from source.
**Non-code edge creation guidance:**
- **Config files:** Look at the config file's purpose. `tsconfig.json` configures all `.ts` files; `package.json` configures the build. Create `configures` edges to the most relevant entry points or directories.
- **Doc files:** If the doc mentions specific files, components, or modules by name, create `documents` edges. README.md typically documents the project entry point.
- **Dockerfiles:** Create `deploys` edges to the main application entry point or the directory being COPY'd into the container.
- **SQL files:** Create `migrates` edges between migration files and the table nodes they modify. Create `defines_schema` edges from schema files to API handlers that serve that data.
- **CI configs:** Create `triggers` edges to the deployment targets or test suites they invoke.
- **GraphQL/Protobuf schemas:** Create `defines_schema` edges to the code files that implement the resolvers or service handlers.
Do NOT use edge types not listed in the tables above.
## Node Types and ID Conventions
@@ -221,8 +427,16 @@ You MUST use these exact prefixes for node IDs:
| File | `file:<relative-path>` | `file:src/index.ts` |
| Function | `function:<relative-path>:<function-name>` | `function:src/utils.ts:formatDate` |
| Class | `class:<relative-path>:<class-name>` | `class:src/models/User.ts:User` |
| Config | `config:<relative-path>` | `config:tsconfig.json` |
| Document | `document:<relative-path>` | `document:README.md` |
| Service | `service:<relative-path>` | `service:Dockerfile` |
| Table | `table:<relative-path>:<table-name>` | `table:migrations/001.sql:users` |
| Endpoint | `endpoint:<relative-path>:<endpoint-name>` | `endpoint:api/openapi.yaml:/users` |
| Pipeline | `pipeline:<relative-path>` | `pipeline:.github/workflows/ci.yml` |
| Schema | `schema:<relative-path>` | `schema:schema.graphql` |
| Resource | `resource:<relative-path>` | `resource:main.tf` |
**Scope restriction:** Only produce `file:`, `function:`, and `class:` nodes. The `module:` and `concept:` node types are reserved for higher-level analysis and MUST NOT be created by this agent.
**Scope restriction:** Only produce node types listed above. The `module:` and `concept:` node types are reserved for higher-level analysis and MUST NOT be created by this agent.
## Output Format
@@ -241,6 +455,34 @@ Produce a single, valid JSON block. Validate it mentally before writing -- malfo
"complexity": "simple",
"languageNotes": "TypeScript barrel file using re-exports."
},
{
"id": "config:tsconfig.json",
"type": "config",
"name": "tsconfig.json",
"filePath": "tsconfig.json",
"summary": "TypeScript compiler configuration enabling strict mode with path aliases for monorepo packages.",
"tags": ["configuration", "typescript", "build-system"],
"complexity": "simple"
},
{
"id": "document:README.md",
"type": "document",
"name": "README.md",
"filePath": "README.md",
"summary": "Project overview documentation with getting-started guide, API reference, and contribution guidelines.",
"tags": ["documentation", "entry-point", "overview"],
"complexity": "moderate"
},
{
"id": "service:Dockerfile",
"type": "service",
"name": "Dockerfile",
"filePath": "Dockerfile",
"summary": "Multi-stage Docker build producing a minimal Node.js production image with health checks.",
"tags": ["containerization", "infrastructure", "deployment"],
"complexity": "moderate",
"languageNotes": "Multi-stage builds reduce image size by separating build dependencies from runtime."
},
{
"id": "function:src/utils.ts:formatDate",
"type": "function",
@@ -266,6 +508,27 @@ Produce a single, valid JSON block. Validate it mentally before writing -- malfo
"type": "contains",
"direction": "forward",
"weight": 1.0
},
{
"source": "config:tsconfig.json",
"target": "file:src/index.ts",
"type": "configures",
"direction": "forward",
"weight": 0.6
},
{
"source": "document:README.md",
"target": "file:src/index.ts",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "service:Dockerfile",
"target": "file:src/index.ts",
"type": "deploys",
"direction": "forward",
"weight": 0.7
}
]
}
@@ -273,14 +536,14 @@ Produce a single, valid JSON block. Validate it mentally before writing -- malfo
**Required fields for every node:**
- `id` (string) -- must follow the ID conventions above
- `type` (string) -- one of: `file`, `function`, `class`
- `type` (string) -- one of: `file`, `function`, `class`, `config`, `document`, `service`, `table`, `endpoint`, `pipeline`, `schema`, `resource`
- `name` (string) -- display name (filename for file nodes, function/class name for others)
- `summary` (string) -- 1-2 sentence description, NEVER empty
- `tags` (string[]) -- 3-5 lowercase hyphenated tags, NEVER empty
- `complexity` (string) -- one of: `simple`, `moderate`, `complex`
**Conditionally required fields:**
- `filePath` (string) -- REQUIRED for `file` nodes, optional for others
- `filePath` (string) -- REQUIRED for file-level nodes (file, config, document, service, pipeline, schema, resource), optional for sub-file nodes
- `lineRange` ([number, number]) -- include for `function` and `class` nodes, sourced directly from script output
**Optional fields:**
@@ -289,9 +552,9 @@ Produce a single, valid JSON block. Validate it mentally before writing -- malfo
**Required fields for every edge:**
- `source` (string) -- must reference an existing node `id` in your output or a known node from the project
- `target` (string) -- must reference an existing node `id` in your output or a known node from the project
- `type` (string) -- must be one of the 8 edge types listed above
- `type` (string) -- must be one of the valid edge types listed above
- `direction` (string) -- always `forward`
- `weight` (number) -- must match the weight specified in the edge type table
- `weight` (number) -- must match the weight specified in the edge type tables
## Language and Framework Quick Reference
@@ -310,6 +573,16 @@ Use these hints to improve tag and edge accuracy for common patterns. Your train
| `manage.py` at the project root | `entry-point` |
| `mod.rs` in a directory | `barrel` |
| `main.go` in a `cmd/` subdirectory | `entry-point` |
| Dockerfile | `containerization`, `infrastructure` |
| docker-compose.yml | `orchestration`, `infrastructure` |
| .github/workflows/*.yml | `ci-cd`, `deployment` |
| *.sql in migrations/ | `database`, `migration` |
| *.graphql or *.gql | `api-schema`, `schema-definition` |
| *.proto | `schema-definition`, `data-pipeline` |
| *.tf | `infrastructure`, `deployment` |
| README.md | `documentation`, `entry-point` |
| CHANGELOG.md | `documentation`, `versioning` |
| .env or .env.example | `configuration`, `security` |
**Edge signals:**
@@ -321,12 +594,17 @@ Use these hints to improve tag and edge accuracy for common patterns. Your train
| Component calls `useContext` or custom context hook | `depends_on` from consumer to context definition |
| Python file uses `from x import y` where x is a project file | `imports` edge (same rule as JS/TS) |
| Go file `import`s an internal package path | `imports` edge to the resolved file |
| Dockerfile COPY from code directory | `deploys` from Dockerfile to code entry point |
| docker-compose references Dockerfile | `depends_on` from compose to Dockerfile |
| CI config runs test commands | `triggers` from CI config to test files |
| SQL migration references table name | `migrates` from migration to table definition |
| GraphQL resolver imports from code | `defines_schema` from schema to resolver |
## Critical Constraints
- NEVER invent file paths. Every `filePath` and every file reference in node IDs must correspond to a real file from the script's output, `batchFiles`, or `batchImportData`.
- NEVER create edges to nodes that do not exist. Only create import edges for paths listed in `batchImportData` — these are already verified project-internal paths.
- ALWAYS create a `file:` node for EVERY file in your batch, even if the file is trivial.
- NEVER create edges to nodes that do not exist. Only create import edges for paths listed in `batchImportData` — these are already verified project-internal paths. For non-code edges (configures, documents, deploys, etc.), only target nodes that exist in your batch or that you know exist from other batches.
- ALWAYS create a node for EVERY file in your batch, even if the file is trivial. Use the appropriate node type based on fileCategory.
- Only create `function:` and `class:` nodes for significant code elements (see significance filter above).
- For import edges, use `batchImportData[filePath]` directly from the input JSON. Do NOT attempt to resolve import paths yourself -- the project scanner already did this deterministically.
- NEVER produce duplicate node IDs within your batch.