@veewo/gitnexus 1.4.11-rc.2 → 1.5.0-rc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/benchmark/u2-e2e/hydration-policy-repeatability-runner.d.ts +55 -0
  2. package/dist/benchmark/u2-e2e/hydration-policy-repeatability-runner.js +190 -0
  3. package/dist/benchmark/u2-e2e/hydration-policy-repeatability-runner.test.js +13 -0
  4. package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.d.ts +22 -0
  5. package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.js +100 -0
  6. package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.test.d.ts +1 -0
  7. package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.test.js +13 -0
  8. package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.d.ts +27 -0
  9. package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.js +118 -0
  10. package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.test.d.ts +1 -0
  11. package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.test.js +16 -0
  12. package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.d.ts +60 -0
  13. package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.js +331 -0
  14. package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.test.d.ts +1 -0
  15. package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.test.js +42 -0
  16. package/dist/benchmark/u2-e2e/reload-v1-acceptance-runner.js +4 -4
  17. package/dist/benchmark/unity-lazy-context-sampler.d.ts +6 -0
  18. package/dist/benchmark/unity-lazy-context-sampler.js +49 -13
  19. package/dist/benchmark/unity-lazy-context-sampler.test.js +4 -0
  20. package/dist/cli/ai-context.js +6 -1
  21. package/dist/cli/eval-server.js +0 -3
  22. package/dist/cli/index.js +8 -0
  23. package/dist/cli/mcp.js +0 -3
  24. package/dist/cli/rule-lab.d.ts +42 -0
  25. package/dist/cli/rule-lab.js +157 -0
  26. package/dist/cli/rule-lab.test.d.ts +1 -0
  27. package/dist/cli/rule-lab.test.js +11 -0
  28. package/dist/cli/tool.d.ts +7 -1
  29. package/dist/cli/tool.js +6 -0
  30. package/dist/core/config/unity-config.d.ts +20 -0
  31. package/dist/core/config/unity-config.js +46 -0
  32. package/dist/core/graph/types.d.ts +1 -1
  33. package/dist/core/ingestion/pipeline.js +38 -13
  34. package/dist/core/ingestion/unity-lifecycle-synthetic-calls.d.ts +0 -2
  35. package/dist/core/ingestion/unity-lifecycle-synthetic-calls.js +26 -213
  36. package/dist/core/ingestion/unity-lifecycle-synthetic-calls.test.js +1 -1
  37. package/dist/core/ingestion/unity-resource-processor.js +87 -22
  38. package/dist/core/ingestion/unity-resource-processor.test.js +67 -2
  39. package/dist/core/ingestion/unity-runtime-binding-rules.d.ts +11 -0
  40. package/dist/core/ingestion/unity-runtime-binding-rules.js +179 -0
  41. package/dist/core/unity/options.d.ts +4 -0
  42. package/dist/core/unity/options.js +18 -0
  43. package/dist/core/unity/options.test.js +11 -1
  44. package/dist/core/unity/resolver.js +11 -1
  45. package/dist/core/unity/resolver.test.js +62 -0
  46. package/dist/core/unity/yaml-object-graph.js +1 -1
  47. package/dist/core/unity/yaml-object-graph.test.js +16 -0
  48. package/dist/mcp/local/derived-process-reader.d.ts +2 -0
  49. package/dist/mcp/local/derived-process-reader.js +15 -0
  50. package/dist/mcp/local/local-backend.d.ts +56 -0
  51. package/dist/mcp/local/local-backend.js +1003 -53
  52. package/dist/mcp/local/local-backend.unity-merge.test.js +1 -1
  53. package/dist/mcp/local/process-confidence.js +1 -1
  54. package/dist/mcp/local/process-evidence.d.ts +1 -0
  55. package/dist/mcp/local/process-evidence.js +22 -0
  56. package/dist/mcp/local/process-evidence.test.js +11 -1
  57. package/dist/mcp/local/process-ref.d.ts +24 -0
  58. package/dist/mcp/local/process-ref.js +33 -0
  59. package/dist/mcp/local/process-ref.test.d.ts +1 -0
  60. package/dist/mcp/local/process-ref.test.js +24 -0
  61. package/dist/mcp/local/runtime-chain-verify.d.ts +15 -1
  62. package/dist/mcp/local/runtime-chain-verify.js +191 -187
  63. package/dist/mcp/local/runtime-chain-verify.test.js +546 -19
  64. package/dist/mcp/local/runtime-claim-rule-registry.d.ts +63 -0
  65. package/dist/mcp/local/runtime-claim-rule-registry.js +308 -0
  66. package/dist/mcp/local/runtime-claim-rule-registry.test.d.ts +1 -0
  67. package/dist/mcp/local/runtime-claim-rule-registry.test.js +215 -0
  68. package/dist/mcp/local/runtime-claim.d.ts +38 -0
  69. package/dist/mcp/local/runtime-claim.js +54 -0
  70. package/dist/mcp/local/runtime-claim.test.d.ts +1 -0
  71. package/dist/mcp/local/runtime-claim.test.js +27 -0
  72. package/dist/mcp/local/unity-enrichment.d.ts +1 -0
  73. package/dist/mcp/local/unity-enrichment.js +1 -1
  74. package/dist/mcp/local/unity-evidence-view.d.ts +26 -0
  75. package/dist/mcp/local/unity-evidence-view.js +96 -0
  76. package/dist/mcp/local/unity-evidence-view.test.d.ts +1 -0
  77. package/dist/mcp/local/unity-evidence-view.test.js +39 -0
  78. package/dist/mcp/local/unity-lazy-hydrator.d.ts +2 -2
  79. package/dist/mcp/local/unity-lazy-hydrator.js +3 -3
  80. package/dist/mcp/local/unity-lazy-hydrator.test.js +4 -4
  81. package/dist/mcp/local/unity-parity-cache.js +2 -6
  82. package/dist/mcp/local/unity-parity-seed-loader.d.ts +1 -0
  83. package/dist/mcp/local/unity-parity-seed-loader.js +10 -16
  84. package/dist/mcp/local/unity-parity-seed-loader.test.js +3 -12
  85. package/dist/mcp/local/unity-runtime-hydration.d.ts +3 -2
  86. package/dist/mcp/local/unity-runtime-hydration.js +13 -16
  87. package/dist/mcp/local/unity-runtime-hydration.test.js +15 -1
  88. package/dist/mcp/resources.js +13 -0
  89. package/dist/mcp/tools.js +166 -13
  90. package/dist/rule-lab/analyze.d.ts +12 -0
  91. package/dist/rule-lab/analyze.js +90 -0
  92. package/dist/rule-lab/analyze.test.d.ts +1 -0
  93. package/dist/rule-lab/analyze.test.js +28 -0
  94. package/dist/rule-lab/compile.d.ts +5 -0
  95. package/dist/rule-lab/compile.js +51 -0
  96. package/dist/rule-lab/compiled-bundles.d.ts +30 -0
  97. package/dist/rule-lab/compiled-bundles.js +36 -0
  98. package/dist/rule-lab/curate.d.ts +32 -0
  99. package/dist/rule-lab/curate.js +134 -0
  100. package/dist/rule-lab/curate.test.d.ts +1 -0
  101. package/dist/rule-lab/curate.test.js +72 -0
  102. package/dist/rule-lab/discover.d.ts +13 -0
  103. package/dist/rule-lab/discover.js +74 -0
  104. package/dist/rule-lab/discover.test.d.ts +1 -0
  105. package/dist/rule-lab/discover.test.js +42 -0
  106. package/dist/rule-lab/paths.d.ts +21 -0
  107. package/dist/rule-lab/paths.js +37 -0
  108. package/dist/rule-lab/paths.test.d.ts +1 -0
  109. package/dist/rule-lab/paths.test.js +46 -0
  110. package/dist/rule-lab/promote.d.ts +26 -0
  111. package/dist/rule-lab/promote.js +314 -0
  112. package/dist/rule-lab/promote.test.d.ts +1 -0
  113. package/dist/rule-lab/promote.test.js +164 -0
  114. package/dist/rule-lab/regress.d.ts +60 -0
  115. package/dist/rule-lab/regress.js +122 -0
  116. package/dist/rule-lab/regress.test.d.ts +1 -0
  117. package/dist/rule-lab/regress.test.js +68 -0
  118. package/dist/rule-lab/review-pack.d.ts +31 -0
  119. package/dist/rule-lab/review-pack.js +125 -0
  120. package/dist/rule-lab/review-pack.test.d.ts +1 -0
  121. package/dist/rule-lab/review-pack.test.js +49 -0
  122. package/dist/rule-lab/types.d.ts +99 -0
  123. package/dist/rule-lab/types.js +1 -0
  124. package/package.json +1 -1
  125. package/skills/_shared/unity-hydration-contract.md +11 -0
  126. package/skills/_shared/unity-ui-trace-contract.md +33 -0
  127. package/skills/gitnexus-cli.md +11 -25
  128. package/skills/gitnexus-guide.md +2 -0
  129. package/skills/gitnexus-unity-rule-gen.md +318 -0
  130. package/dist/core/ingestion/unity-lifecycle-config.d.ts +0 -5
  131. package/dist/core/ingestion/unity-lifecycle-config.js +0 -25
  132. package/dist/mcp/local/unity-lazy-config.d.ts +0 -6
  133. package/dist/mcp/local/unity-lazy-config.js +0 -7
  134. package/dist/mcp/local/unity-lazy-config.test.js +0 -9
  135. package/dist/mcp/local/unity-process-confidence-config.d.ts +0 -1
  136. package/dist/mcp/local/unity-process-confidence-config.js +0 -4
  137. package/dist/mcp/local/unity-runtime-chain-verify-config.d.ts +0 -1
  138. package/dist/mcp/local/unity-runtime-chain-verify-config.js +0 -10
  139. /package/dist/{mcp/local/unity-lazy-config.test.d.ts → benchmark/u2-e2e/hydration-policy-repeatability-runner.test.d.ts} +0 -0
@@ -0,0 +1,99 @@
1
+ export type RuleLabScope = 'full' | 'diff';
2
+ export type RuntimeClaimFailureReason = 'rule_not_matched' | 'rule_matched_but_evidence_missing' | 'rule_matched_but_verification_failed' | 'gate_disabled';
3
+ export interface RuleLabSlice {
4
+ id: string;
5
+ trigger_family: string;
6
+ resource_types: string[];
7
+ host_base_type: string[];
8
+ required_hops?: string[];
9
+ }
10
+ export interface RuleLabManifest {
11
+ run_id: string;
12
+ repo_path: string;
13
+ scope: RuleLabScope;
14
+ generated_at: string;
15
+ slices: RuleLabSlice[];
16
+ next_actions: string[];
17
+ stages: string[];
18
+ }
19
+ export interface RuleLabCandidateHop {
20
+ hop_type: string;
21
+ anchor: string;
22
+ snippet: string;
23
+ }
24
+ export interface RuleLabCandidate {
25
+ id: string;
26
+ title: string;
27
+ rule_hint?: string;
28
+ topology?: Array<{
29
+ hop: string;
30
+ from: Record<string, unknown>;
31
+ to: Record<string, unknown>;
32
+ edge: {
33
+ kind: string;
34
+ };
35
+ constraints?: Record<string, unknown>;
36
+ }>;
37
+ stats?: {
38
+ covered: number;
39
+ total: number;
40
+ conflicts: number;
41
+ coverage_rate: number;
42
+ conflict_rate: number;
43
+ };
44
+ counter_examples?: Array<{
45
+ reason: string;
46
+ missing_hop?: string;
47
+ evidence_anchor?: string;
48
+ }>;
49
+ evidence: {
50
+ hops: RuleLabCandidateHop[];
51
+ };
52
+ }
53
+ export interface RuleDslMatch {
54
+ trigger_tokens: string[];
55
+ symbol_kind?: string[];
56
+ module_scope?: string[];
57
+ resource_types?: string[];
58
+ host_base_type?: string[];
59
+ }
60
+ export interface RuleDslTopologyHop {
61
+ hop: string;
62
+ from: Record<string, unknown>;
63
+ to: Record<string, unknown>;
64
+ edge: {
65
+ kind: string;
66
+ };
67
+ constraints?: Record<string, unknown>;
68
+ }
69
+ export interface RuleDslClosure {
70
+ required_hops: string[];
71
+ failure_map: Partial<Record<string, RuntimeClaimFailureReason>>;
72
+ }
73
+ export interface RuleDslClaims {
74
+ guarantees: string[];
75
+ non_guarantees: string[];
76
+ next_action: string;
77
+ }
78
+ export interface UnityResourceBinding {
79
+ kind: 'asset_ref_loads_components' | 'method_triggers_field_load';
80
+ ref_field_pattern?: string;
81
+ target_entry_points?: string[];
82
+ host_class_pattern?: string;
83
+ field_name?: string;
84
+ loader_methods?: string[];
85
+ }
86
+ export interface LifecycleOverrides {
87
+ additional_entry_points?: string[];
88
+ scope?: string;
89
+ }
90
+ export interface RuleDslDraft {
91
+ id: string;
92
+ version: string;
93
+ match: RuleDslMatch;
94
+ topology: RuleDslTopologyHop[];
95
+ closure: RuleDslClosure;
96
+ claims: RuleDslClaims;
97
+ resource_bindings?: UnityResourceBinding[];
98
+ lifecycle_overrides?: LifecycleOverrides;
99
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veewo/gitnexus",
3
- "version": "1.4.11-rc.2",
3
+ "version": "1.5.0-rc",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
@@ -0,0 +1,11 @@
1
+ # Unity Hydration Contract
2
+
3
+ When querying Unity resource evidence via `query` or `context`:
4
+
5
+ 1. Call with `unity_resources: "on"` and `unity_hydration_mode: "compact"` (fast path).
6
+ 2. Inspect `hydrationMeta` in the response:
7
+ - `needsParityRetry: true` → rerun the same call with `unity_hydration_mode: "parity"`
8
+ - `isComplete: true` → keep compact result
9
+ 3. Treat `parity` as the completeness path for advanced verification only.
10
+
11
+ CLI equivalents: `--unity-resources on --unity-hydration compact` (or `parity`).
@@ -0,0 +1,33 @@
1
+ # Unity UI Trace Contract
2
+
3
+ Trigger this contract for UIToolkit visual semantics (layout, element, style, selector behavior).
4
+
5
+ ## Input
6
+
7
+ - `target`: C# class name or UXML path
8
+ - `goal`: `asset_refs | template_refs | selector_bindings`
9
+ - `selector_mode` (optional): `balanced` (default) or `strict`
10
+
11
+ ## Goals
12
+
13
+ - `asset_refs`: which prefab/asset references the target UXML
14
+ - `template_refs`: which UXML templates are referenced by the target UXML
15
+ - `selector_bindings`: C# `AddToClassList/Q(className)` → USS selector evidence chain
16
+
17
+ ## Selector Modes (selector_bindings only)
18
+
19
+ - `balanced` (default): match class tokens inside composite selectors — higher recall
20
+ - `strict`: only exact `.className` selectors — higher precision
21
+
22
+ ## Output Fields
23
+
24
+ - `results[].evidence_chain`: each hop has `path + line + snippet`
25
+ - `results[].score`: ranking score (higher = higher priority)
26
+ - `results[].confidence`: `high|medium|low`
27
+ - `diagnostics`: `not_found|ambiguous`
28
+
29
+ ## Default Order
30
+
31
+ 1. `asset_refs` — confirm asset reference chain exists
32
+ 2. `template_refs` — confirm template reference chain exists
33
+ 3. `selector_bindings` — use `balanced` first; switch to `strict` if false positives suspected
@@ -42,13 +42,18 @@ $GN analyze
42
42
 
43
43
  Run from the project root. This parses all source files, builds the knowledge graph, writes it to `.gitnexus/`, and generates CLAUDE.md / AGENTS.md context files.
44
44
 
45
- | Flag | Effect |
46
- | -------------- | ---------------------------------------------------------------- |
47
- | `--force` | Force full re-index even if up to date |
48
- | `--embeddings` | Enable embedding generation for semantic search (off by default) |
45
+ | Flag | Effect |
46
+ | -------------------------- | ----------------------------------------------------------------------------------------- |
47
+ | `--force` | Force full re-index even if up to date |
48
+ | `--embeddings` | Enable embedding generation for semantic search (off by default) |
49
+ | `--extensions <ext>` | Limit parsing to specific file types (e.g., `--extensions ".cs .meta"` for Unity) |
50
+ | `--scope-prefix <prefix>` | Limit analysis to a path prefix (e.g., `--scope-prefix Assets/` for Unity) |
51
+ | `--skills` | Generate repo-specific skill files from detected code communities |
49
52
 
50
53
  **When to run:** First time in a project, after major code changes, or when `gitnexus://repo/{name}/context` reports the index is stale. In Claude Code, a PostToolUse hook runs `analyze` automatically after `git commit` and `git merge`, preserving embeddings if previously generated.
51
54
 
55
+ **Unity projects:** Add `--extensions ".cs .meta"` to ensure Unity asset edges (`UNITY_ASSET_GUID_REF`, `UNITY_COMPONENT_INSTANCE`) are parsed. Add `--scope-prefix Assets/` to limit scope if all code lives under `Assets/`.
56
+
52
57
  ### status — Check index freshness
53
58
 
54
59
  ```bash
@@ -131,33 +136,14 @@ $GN context ReloadNode --repo neonspark --unity-resources on --unity-hydration c
131
136
 
132
137
  ### unity-ui-trace — Unity UI evidence tracing workflow
133
138
 
139
+ For full workflow details, load: `_shared/unity-ui-trace-contract.md`
140
+
134
141
  ```bash
135
142
  $GN unity-ui-trace "Assets/NEON/VeewoUI/Uxml/BarScreen/Patch/PatchItemPreview.uxml" --goal asset_refs --repo neonspark
136
143
  $GN unity-ui-trace "Assets/NEON/VeewoUI/Uxml/BarScreen/CoreScreen.uxml" --goal template_refs --repo neonspark
137
144
  $GN unity-ui-trace "Assets/NEON/VeewoUI/Uxml/BarScreen/Patch/PatchItemPreview.uxml" --goal selector_bindings --selector-mode balanced --repo neonspark
138
145
  ```
139
146
 
140
- Supported goals:
141
- - `asset_refs`: 哪些 prefab/asset 引用了目标 UXML
142
- - `template_refs`: 目标 UXML 里引用了哪些模板 UXML
143
- - `selector_bindings`: C# `AddToClassList/Q(className)` 到 USS 选择器证据链
144
-
145
- Selector mode(仅 `selector_bindings` 生效):
146
- - `--selector-mode balanced`(默认): 复合选择器 token 匹配,召回更高
147
- - `--selector-mode strict`: 仅匹配精确 `.className` 选择器,精度更高
148
-
149
- 输出字段解读:
150
- - `results[].evidence_chain`: 每跳都有 `path + line + snippet`
151
- - `results[].score`: 排序分数(越高越优先)
152
- - `results[].confidence`: `high|medium|low`(基于 score)
153
- - `diagnostics`: `not_found|ambiguous` 诊断
154
-
155
- 推荐排查顺序(实仓):
156
- 1. 先跑 `asset_refs`,确认资源链是否存在
157
- 2. 再跑 `template_refs`,确认模板链是否存在
158
- 3. 最后跑 `selector_bindings`,默认 `balanced`
159
- 4. 若怀疑误报,复跑 `--selector-mode strict` 对比
160
-
161
147
  ## After Indexing
162
148
 
163
149
  1. **Read `gitnexus://repo/{name}/context`** to verify the index loaded
@@ -27,6 +27,7 @@ For any task involving code understanding, debugging, impact analysis, or refact
27
27
  | Rename / extract / split / refactor | `gitnexus-refactoring` |
28
28
  | Tools, resources, schema reference | `gitnexus-guide` (this file) |
29
29
  | Index, status, clean, wiki CLI commands | `gitnexus-cli` |
30
+ | Create Unity analyze_rules interactively | `gitnexus-unity-rule-gen` |
30
31
 
31
32
  ## Tools Reference
32
33
 
@@ -99,6 +100,7 @@ Lightweight reads (~100-500 tokens) for navigation:
99
100
 
100
101
  **Nodes:** File, Function, Class, Interface, Method, Community, Process
101
102
  **Edges (via CodeRelation.type):** CALLS, IMPORTS, EXTENDS, IMPLEMENTS, DEFINES, MEMBER_OF, STEP_IN_PROCESS
103
+ **Unity edges:** UNITY_ASSET_GUID_REF (serialized field → asset), UNITY_COMPONENT_INSTANCE (class → asset file)
102
104
 
103
105
  ```cypher
104
106
  MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "myFunc"})
@@ -0,0 +1,318 @@
1
+ ---
2
+ name: gitnexus-unity-rule-gen
3
+ description: "Interactive workflow for generating Unity analyze_rules: collect chain clues from user, explore graph to fill parameters, generate rule YAML, compile to bundle, analyze, and verify. Use when: 'create unity rules', 'generate analyze rules', 'add resource binding rules', 'unity rule gen'."
4
+ ---
5
+
6
+ # Unity Analyze Rules 交互式生成工作流
7
+
8
+ 本技能引导 agent 从用户描述的自然语言调用链路线索出发,通过图谱探索补全参数,交互式生成 `analyze_rules` 规则。支持一次录入多条规则,一次性 analyze 后逐一验证。
9
+
10
+ ## Phase 0: 初始化
11
+
12
+ ```
13
+ 1. 确认 gitnexus CLI 可用(gitnexus --version)
14
+ 2. 确认目标仓库路径(询问用户或从 cwd 推断)
15
+ 3. 确认仓库已索引(gitnexus status),未索引则先 analyze
16
+ 4. 确认 UNITY_ASSET_GUID_REF 和 UNITY_COMPONENT_INSTANCE 边存在:
17
+ ```
18
+
19
+ ```
20
+ mcp__gitnexus__cypher:
21
+ query: |
22
+ MATCH ()-[r:CodeRelation]->()
23
+ WHERE r.type IN ['UNITY_ASSET_GUID_REF', 'UNITY_COMPONENT_INSTANCE']
24
+ RETURN r.type AS edgeType, count(*) AS cnt
25
+ repo: <repo-name>
26
+ ```
27
+
28
+ 如果这两种边不存在,说明索引时未启用 Unity 资源解析,需要重新 analyze,**必须加 Unity 参数**:
29
+
30
+ ```bash
31
+ gitnexus analyze --force --extensions ".cs .meta"
32
+ # 如果所有代码都在 Assets/ 下,可加 --scope-prefix Assets/ 缩短分析时间
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Phase 1: 规则录入循环
38
+
39
+ ```
40
+ loop:
41
+ 1.1 收集用户链路线索
42
+ 1.2 图谱探索补全
43
+ 1.3 多路径确认
44
+ 1.4 binding 类型判定
45
+ 1.5 生成规则 YAML 并暂存
46
+ 1.6 询问用户:是否继续录入下一条规则?
47
+ - 是 → 回到 1.1
48
+ - 否 → 进入 Phase 2
49
+ ```
50
+
51
+ ### 1.1 收集用户链路线索
52
+
53
+ 向用户询问:
54
+
55
+ | 信息 | 问题 | 示例 |
56
+ |------|------|------|
57
+ | 场景名称 | 你想验证哪个资源→代码链路? | weapon-powerup-gungraph |
58
+ | 资源引用字段 | 哪些序列化字段名触发资源加载? | `gungraph\|graph` |
59
+ | 目标入口方法 | 加载的资源上哪些方法会被触发? | OnEnable, Awake |
60
+ | 持有字段的类 | 哪些类持有触发加载的字段? | WeaponPowerUp |
61
+ | 加载方法 | 哪些方法触发资源加载? | Equip |
62
+ | 额外 lifecycle | 项目有自定义入口方法吗? | Init |
63
+ | lifecycle 范围 | 自定义入口方法的作用范围? | Assets/Code/Graph |
64
+
65
+ ### 1.2 图谱探索补全
66
+
67
+ 用户不确定某些字段时,按优先级探索:**Cypher 直查 > gitnexus context > 文件 grep**
68
+
69
+ ```
70
+ # 查找资源引用字段名
71
+ mcp__gitnexus__cypher:
72
+ query: |
73
+ MATCH ()-[r:CodeRelation {type:'UNITY_ASSET_GUID_REF'}]->()
74
+ RETURN DISTINCT r.reason
75
+ LIMIT 20
76
+ repo: <repo-name>
77
+
78
+ # 查找挂载在资源上的组件类
79
+ mcp__gitnexus__cypher:
80
+ query: |
81
+ MATCH (c:Class)-[r:CodeRelation {type:'UNITY_COMPONENT_INSTANCE'}]->(f:File)
82
+ WHERE f.filePath CONTAINS '.asset'
83
+ RETURN c.name, f.filePath
84
+ LIMIT 20
85
+ repo: <repo-name>
86
+
87
+ # 查找特定类的方法列表
88
+ mcp__gitnexus__context:
89
+ name: <ClassName>
90
+ repo: <repo-name>
91
+ ```
92
+
93
+ 如果图谱查询无结果,回退到文件直读:
94
+
95
+ ```
96
+ # 查找 [SerializeField] 字段
97
+ Grep: pattern="\[SerializeField\]" path=<Assets目录>
98
+
99
+ # 查找特定方法定义
100
+ Grep: pattern="void Init\b|void Setup\b" path=<Assets目录>
101
+ ```
102
+
103
+ ### 1.3 多路径确认
104
+
105
+ - 同一位置 ≥2 候选路径 → **向用户确认**选择哪条
106
+ - 探索 3 步无结果 → **向用户补充提问**
107
+
108
+ ### 1.4 binding 类型判定
109
+
110
+ | 链路特征 | binding kind | 说明 |
111
+ |---------|-------------|------|
112
+ | asset GUID 引用 → 目标资源组件激活 | `asset_ref_loads_components` | 序列化字段引用 asset,加载时触发组件 lifecycle |
113
+ | 方法调用 → 字段引用的资源加载 | `method_triggers_field_load` | 特定方法触发序列化字段引用的资源加载 |
114
+ | 项目自定义入口方法 | `lifecycle_overrides` | 非标准 Unity lifecycle 的自定义入口 |
115
+
116
+ ### 1.5 生成规则 YAML
117
+
118
+ 使用以下模板,根据收集的线索填充:
119
+
120
+ ```yaml
121
+ id: unity.<scenario-name>.v2
122
+ version: 2.0.0
123
+ family: analyze_rules
124
+ trigger_family: <scenario-name>
125
+ resource_types:
126
+ - asset
127
+ host_base_type:
128
+ - MonoBehaviour
129
+ - ScriptableObject
130
+
131
+ match:
132
+ trigger_tokens:
133
+ - <token1>
134
+ - <token2>
135
+ host_base_type:
136
+ - MonoBehaviour
137
+ - ScriptableObject
138
+ resource_types:
139
+ - asset
140
+
141
+ topology:
142
+
143
+ resource_bindings:
144
+ - kind: asset_ref_loads_components
145
+ ref_field_pattern: "<field_pattern>"
146
+ target_entry_points:
147
+ - OnEnable
148
+ - Awake
149
+
150
+ - kind: method_triggers_field_load
151
+ host_class_pattern: "<class_pattern>"
152
+ field_name: "<field_name>"
153
+ loader_methods:
154
+ - <method_name>
155
+
156
+ lifecycle_overrides:
157
+ additional_entry_points:
158
+ - <custom_entry>
159
+ scope: "<path_prefix>"
160
+
161
+ closure:
162
+ required_hops:
163
+ - resource
164
+ - guid_map
165
+ - code_loader
166
+ - code_runtime
167
+
168
+ claims:
169
+ guarantees:
170
+ - resource_to_runtime_chain_closed
171
+ non_guarantees:
172
+ - no_runtime_execution
173
+ - no_dynamic_data_flow_proof
174
+ ```
175
+
176
+ ### 1.6 暂存并询问
177
+
178
+ 将生成的 YAML 暂存(不写入文件),向用户确认:
179
+
180
+ > 规则 `<ruleId>` 已生成。是否继续录入下一条规则?
181
+
182
+ - 是 → 回到 1.1
183
+ - 否 → 进入 Phase 2
184
+
185
+ ---
186
+
187
+ ## Phase 2: 写入 + compile + analyze
188
+
189
+ ### 2.1 写入规则文件
190
+
191
+ ```bash
192
+ mkdir -p "$TARGET_REPO/.gitnexus/rules/approved"
193
+ # 将每条暂存的 YAML 写入对应文件
194
+ # 文件名: approved/<ruleId>.yaml
195
+ ```
196
+
197
+ ### 2.2 更新 catalog.json
198
+
199
+ ```bash
200
+ # 如果 catalog.json 不存在,创建初始结构
201
+ if [ ! -f "$TARGET_REPO/.gitnexus/rules/catalog.json" ]; then
202
+ echo '{"version":1,"rules":[]}' > "$TARGET_REPO/.gitnexus/rules/catalog.json"
203
+ fi
204
+ ```
205
+
206
+ 向 `rules` 数组追加每条规则的条目:
207
+
208
+ ```json
209
+ {
210
+ "id": "<ruleId>",
211
+ "version": "2.0.0",
212
+ "enabled": true,
213
+ "file": "approved/<ruleId>.yaml",
214
+ "family": "analyze_rules"
215
+ }
216
+ ```
217
+
218
+ ### 2.3 编译规则
219
+
220
+ ```bash
221
+ gitnexus rule-lab compile --repo-path "$TARGET_REPO"
222
+ ```
223
+
224
+ ### 2.4 重建索引
225
+
226
+ ```bash
227
+ gitnexus analyze "$TARGET_REPO" --force --extensions ".cs .meta"
228
+ # 如果所有代码都在 Assets/ 下,可加 --scope-prefix Assets/
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Phase 3: 逐一验证
234
+
235
+ 对每条规则执行 4 项验证,每项给出 PASS/FAIL 判定。
236
+
237
+ ### 验证 1: 合成边存在性
238
+
239
+ ```
240
+ mcp__gitnexus__cypher:
241
+ query: |
242
+ MATCH (a)-[r:CodeRelation {type: 'CALLS'}]->(b)
243
+ WHERE r.reason STARTS WITH 'unity-rule-'
244
+ RETURN r.reason AS reason, count(*) AS cnt
245
+ ORDER BY cnt DESC
246
+ repo: <repo-name>
247
+ ```
248
+
249
+ **PASS**: 返回 ≥1 行,且 `reason` 包含规则 ID。
250
+ **FAIL 诊断**: 规则未被 pipeline 加载 → 检查 catalog.json 的 `family` 字段。
251
+
252
+ ### 验证 2: 运行时链路验证
253
+
254
+ ```
255
+ mcp__gitnexus__query:
256
+ query: "<trigger_token>"
257
+ runtime_chain_verify: "on-demand"
258
+ repo: <repo-name>
259
+ ```
260
+
261
+ **PASS**: `runtime_chain.status === 'verified_full'` 且 `evidence_level === 'verified_chain'`。
262
+ **FAIL 诊断**:
263
+ - `rule_not_matched` → 规则的 `trigger_tokens` 未匹配查询文本
264
+ - `verification_failed` → 图谱中无匹配的 `unity-rule-*` 合成边
265
+
266
+ ### 验证 3: Process 完整性
267
+
268
+ ```
269
+ mcp__gitnexus__context:
270
+ name: "<target_class>"
271
+ repo: <repo-name>
272
+ ```
273
+
274
+ **PASS**: `processes` 中至少有一个包含跨越资源层和代码层的步骤。
275
+ **FAIL 诊断**: 合成边 confidence 过低 → 检查 `RULE_EDGE_CONFIDENCE`(应为 0.75)。
276
+
277
+ ### 验证 4: 合成边分布
278
+
279
+ ```
280
+ mcp__gitnexus__cypher:
281
+ query: |
282
+ MATCH (a)-[r:CodeRelation {type: 'CALLS'}]->(b)
283
+ WHERE r.reason STARTS WITH 'unity-rule-'
284
+ RETURN
285
+ CASE
286
+ WHEN r.reason CONTAINS 'resource-load' THEN 'resource-load'
287
+ WHEN r.reason CONTAINS 'lifecycle-override' THEN 'lifecycle-override'
288
+ WHEN r.reason CONTAINS 'loader-bridge' THEN 'loader-bridge'
289
+ ELSE 'other'
290
+ END AS edgeKind,
291
+ count(*) AS cnt
292
+ repo: <repo-name>
293
+ ```
294
+
295
+ **PASS**: 三种边类型(resource-load, lifecycle-override, loader-bridge)均有产出。
296
+
297
+ ---
298
+
299
+ ## 失败诊断路径
300
+
301
+ | 症状 | 可能原因 | 修复方向 |
302
+ |------|---------|---------|
303
+ | 验证 1 失败(0 合成边) | 规则未被 compile 或 family 不对 | 检查 catalog.json + compiled bundle |
304
+ | 验证 1 部分(只有 resource-load) | method_triggers_field_load 参数错误 | 检查 host_class_pattern / loader_methods |
305
+ | 验证 2 失败(rule_not_matched) | trigger_tokens 未匹配查询文本 | 调整 match.trigger_tokens |
306
+ | 验证 2 失败(verification_failed) | 合成边 reason 中的 ruleId 不匹配 | 检查规则 ID 一致性 |
307
+ | 验证 3 失败(无 Process) | 合成边 confidence 过低 | 检查 RULE_EDGE_CONFIDENCE(应为 0.75) |
308
+ | lifecycle_overrides 无效 | scope 值不是文件路径前缀 | scope 应匹配 filePath 而非类名 |
309
+
310
+ ---
311
+
312
+ ## 参考文档
313
+
314
+ - 设计文档:`docs/plans/2026-04-04-unity-rule-gen-skill-design.md`
315
+ - YAML 格式定义:设计文档 section 3.3
316
+ - 注入逻辑:`gitnexus/src/core/ingestion/unity-runtime-binding-rules.ts`
317
+ - 规则类型定义:`gitnexus/src/rule-lab/types.ts:90-102`
318
+ - 编译命令:`gitnexus rule-lab compile --repo-path <path>`
@@ -1,5 +0,0 @@
1
- import { type UnityLifecycleSyntheticConfig } from './unity-lifecycle-synthetic-calls.js';
2
- export interface UnityLifecycleConfig extends UnityLifecycleSyntheticConfig {
3
- persistLifecycleProcessMetadata: boolean;
4
- }
5
- export declare const resolveUnityLifecycleConfig: (env: NodeJS.ProcessEnv) => UnityLifecycleConfig;
@@ -1,25 +0,0 @@
1
- import { DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG, } from './unity-lifecycle-synthetic-calls.js';
2
- const TRUE_VALUES = new Set(['1', 'true', 'on', 'yes']);
3
- const parsePositiveInt = (raw, fallback) => {
4
- const value = Number.parseInt(String(raw || '').trim(), 10);
5
- if (!Number.isFinite(value) || value <= 0)
6
- return fallback;
7
- return value;
8
- };
9
- const parseBool = (raw) => {
10
- const normalized = String(raw || '').trim().toLowerCase();
11
- return TRUE_VALUES.has(normalized);
12
- };
13
- export const resolveUnityLifecycleConfig = (env) => {
14
- const enabled = parseBool(env.GITNEXUS_UNITY_LIFECYCLE_SYNTHETIC_CALLS);
15
- const persistLifecycleProcessMetadata = parseBool(env.GITNEXUS_UNITY_LIFECYCLE_PROCESS_PERSIST);
16
- const maxSyntheticEdgesPerClass = parsePositiveInt(env.GITNEXUS_UNITY_LIFECYCLE_SYNTHETIC_MAX_PER_CLASS, DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG.maxSyntheticEdgesPerClass);
17
- const maxSyntheticEdgesTotal = parsePositiveInt(env.GITNEXUS_UNITY_LIFECYCLE_SYNTHETIC_MAX_TOTAL, DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG.maxSyntheticEdgesTotal);
18
- return {
19
- ...DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG,
20
- enabled,
21
- persistLifecycleProcessMetadata,
22
- maxSyntheticEdgesPerClass,
23
- maxSyntheticEdgesTotal,
24
- };
25
- };
@@ -1,6 +0,0 @@
1
- export interface UnityLazyConfig {
2
- maxPendingPathsPerRequest: number;
3
- batchSize: number;
4
- maxHydrationMs: number;
5
- }
6
- export declare function resolveUnityLazyConfig(env: NodeJS.ProcessEnv): UnityLazyConfig;
@@ -1,7 +0,0 @@
1
- export function resolveUnityLazyConfig(env) {
2
- return {
3
- maxPendingPathsPerRequest: Number(env.GITNEXUS_UNITY_LAZY_MAX_PATHS || 120),
4
- batchSize: Number(env.GITNEXUS_UNITY_LAZY_BATCH_SIZE || 30),
5
- maxHydrationMs: Number(env.GITNEXUS_UNITY_LAZY_MAX_MS || 5000),
6
- };
7
- }
@@ -1,9 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { resolveUnityLazyConfig } from './unity-lazy-config.js';
4
- test('resolveUnityLazyConfig provides safe defaults', () => {
5
- const cfg = resolveUnityLazyConfig({});
6
- assert.equal(cfg.maxPendingPathsPerRequest, 120);
7
- assert.equal(cfg.batchSize, 30);
8
- assert.equal(cfg.maxHydrationMs, 5000);
9
- });
@@ -1 +0,0 @@
1
- export declare function resolveUnityProcessConfidenceFieldsEnabled(env: NodeJS.ProcessEnv): boolean;
@@ -1,4 +0,0 @@
1
- export function resolveUnityProcessConfidenceFieldsEnabled(env) {
2
- const raw = String(env.GITNEXUS_UNITY_PROCESS_CONFIDENCE_FIELDS || '').trim().toLowerCase();
3
- return raw === '1' || raw === 'true' || raw === 'on' || raw === 'yes';
4
- }
@@ -1 +0,0 @@
1
- export declare function resolveUnityRuntimeChainVerifyEnabled(env: NodeJS.ProcessEnv): boolean;
@@ -1,10 +0,0 @@
1
- export function resolveUnityRuntimeChainVerifyEnabled(env) {
2
- const raw = String(env.GITNEXUS_UNITY_RUNTIME_CHAIN_VERIFY || '').trim().toLowerCase();
3
- if (!raw)
4
- return true;
5
- if (raw === '0' || raw === 'false' || raw === 'off' || raw === 'no')
6
- return false;
7
- if (raw === '1' || raw === 'true' || raw === 'on' || raw === 'yes')
8
- return true;
9
- return true;
10
- }