@veewo/gitnexus 1.5.0-rc.4 → 1.5.1
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.
- package/dist/benchmark/agent-context/runner.js +3 -0
- package/dist/benchmark/agent-context/runner.test.js +22 -0
- package/dist/benchmark/agent-context/tool-runner.d.ts +7 -6
- package/dist/benchmark/agent-safe-query-context/io.d.ts +2 -0
- package/dist/benchmark/agent-safe-query-context/io.js +86 -0
- package/dist/benchmark/agent-safe-query-context/io.test.d.ts +1 -0
- package/dist/benchmark/agent-safe-query-context/io.test.js +13 -0
- package/dist/benchmark/agent-safe-query-context/report.d.ts +57 -0
- package/dist/benchmark/agent-safe-query-context/report.js +159 -0
- package/dist/benchmark/agent-safe-query-context/report.test.d.ts +1 -0
- package/dist/benchmark/agent-safe-query-context/report.test.js +362 -0
- package/dist/benchmark/agent-safe-query-context/runner.d.ts +44 -0
- package/dist/benchmark/agent-safe-query-context/runner.js +406 -0
- package/dist/benchmark/agent-safe-query-context/runner.test.d.ts +1 -0
- package/dist/benchmark/agent-safe-query-context/runner.test.js +290 -0
- package/dist/benchmark/agent-safe-query-context/semantic-tuple.d.ts +20 -0
- package/dist/benchmark/agent-safe-query-context/semantic-tuple.js +225 -0
- package/dist/benchmark/agent-safe-query-context/semantic-tuple.test.d.ts +1 -0
- package/dist/benchmark/agent-safe-query-context/semantic-tuple.test.js +122 -0
- package/dist/benchmark/agent-safe-query-context/subagent-live.d.ts +47 -0
- package/dist/benchmark/agent-safe-query-context/subagent-live.js +128 -0
- package/dist/benchmark/agent-safe-query-context/subagent-live.test.d.ts +1 -0
- package/dist/benchmark/agent-safe-query-context/subagent-live.test.js +155 -0
- package/dist/benchmark/agent-safe-query-context/telemetry-tool.d.ts +9 -0
- package/dist/benchmark/agent-safe-query-context/telemetry-tool.js +77 -0
- package/dist/benchmark/agent-safe-query-context/types.d.ts +61 -0
- package/dist/benchmark/agent-safe-query-context/types.js +8 -0
- package/dist/benchmark/analyze-runner.d.ts +1 -1
- package/dist/benchmark/analyze-runner.js +4 -3
- package/dist/benchmark/analyze-runner.test.js +7 -0
- package/dist/benchmark/runtime-poc/provenance-artifact.d.ts +47 -0
- package/dist/benchmark/runtime-poc/provenance-artifact.js +89 -0
- package/dist/benchmark/runtime-poc/runner.d.ts +31 -0
- package/dist/benchmark/runtime-poc/runner.js +163 -0
- package/dist/benchmark/u2-e2e/hydration-policy-repeatability-runner.d.ts +8 -0
- package/dist/benchmark/u2-e2e/hydration-policy-repeatability-runner.js +21 -0
- package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.d.ts +0 -1
- package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.js +53 -51
- package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.test.js +0 -1
- package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.d.ts +1 -1
- package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.js +82 -18
- package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.test.js +1 -2
- package/dist/benchmark/u2-e2e/retrieval-runner.js +15 -7
- package/dist/benchmark/u2-e2e/retrieval-runner.test.js +46 -0
- package/dist/cli/ai-context.d.ts +0 -1
- package/dist/cli/ai-context.js +5 -6
- package/dist/cli/ai-context.test.js +8 -0
- package/dist/cli/analyze-options.js +58 -34
- package/dist/cli/analyze-options.test.js +57 -0
- package/dist/cli/analyze-runtime-summary.js +2 -0
- package/dist/cli/analyze-runtime-summary.test.js +12 -0
- package/dist/cli/analyze-summary.d.ts +4 -0
- package/dist/cli/analyze-summary.js +43 -0
- package/dist/cli/analyze-summary.test.js +65 -1
- package/dist/cli/analyze.d.ts +11 -0
- package/dist/cli/analyze.js +34 -5
- package/dist/cli/analyze.test.d.ts +1 -0
- package/dist/cli/analyze.test.js +25 -0
- package/dist/cli/benchmark-agent-context.js +1 -1
- package/dist/cli/benchmark-agent-safe-query-context.d.ts +20 -0
- package/dist/cli/benchmark-agent-safe-query-context.js +39 -0
- package/dist/cli/benchmark-agent-safe-query-context.test.d.ts +1 -0
- package/dist/cli/benchmark-agent-safe-query-context.test.js +271 -0
- package/dist/cli/benchmark-unity.js +1 -1
- package/dist/cli/benchmark-unity.test.js +5 -1
- package/dist/cli/benchmark.d.ts +29 -0
- package/dist/cli/benchmark.js +55 -0
- package/dist/cli/index.js +27 -2
- package/dist/cli/rule-lab.d.ts +3 -7
- package/dist/cli/rule-lab.js +13 -22
- package/dist/cli/rule-lab.test.js +23 -3
- package/dist/cli/scope-manifest-config.d.ts +9 -0
- package/dist/cli/scope-manifest-config.js +37 -0
- package/dist/cli/setup.js +40 -41
- package/dist/cli/setup.test.js +14 -14
- package/dist/cli/sync-manifest.d.ts +27 -0
- package/dist/cli/sync-manifest.js +200 -0
- package/dist/cli/sync-manifest.test.d.ts +1 -0
- package/dist/cli/sync-manifest.test.js +88 -0
- package/dist/cli/tool.d.ts +2 -0
- package/dist/cli/tool.js +2 -0
- package/dist/core/config/unity-config.d.ts +1 -1
- package/dist/core/config/unity-config.js +1 -1
- package/dist/core/ingestion/call-processor.d.ts +2 -1
- package/dist/core/ingestion/call-processor.js +28 -6
- package/dist/core/ingestion/heritage-processor.d.ts +2 -1
- package/dist/core/ingestion/heritage-processor.js +30 -7
- package/dist/core/ingestion/import-processor.d.ts +2 -1
- package/dist/core/ingestion/import-processor.js +28 -6
- package/dist/core/ingestion/parsing-processor.d.ts +5 -3
- package/dist/core/ingestion/parsing-processor.js +46 -13
- package/dist/core/ingestion/pipeline.js +100 -19
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.test.js +18 -20
- package/dist/core/ingestion/unity-parity-seed.d.ts +2 -1
- package/dist/core/ingestion/unity-parity-seed.js +8 -0
- package/dist/core/ingestion/unity-resource-processor.d.ts +11 -0
- package/dist/core/ingestion/unity-resource-processor.js +102 -0
- package/dist/core/ingestion/unity-resource-processor.test.js +449 -0
- package/dist/core/ingestion/unity-runtime-binding-rules.d.ts +16 -1
- package/dist/core/ingestion/unity-runtime-binding-rules.js +193 -42
- package/dist/core/ingestion/workers/parse-worker.d.ts +2 -0
- package/dist/core/ingestion/workers/parse-worker.js +50 -6
- package/dist/core/lbug/csv-generator.test.js +2 -2
- package/dist/core/tree-sitter/csharp-define-profile.d.ts +6 -0
- package/dist/core/tree-sitter/csharp-define-profile.js +43 -0
- package/dist/core/tree-sitter/csharp-preproc-normalizer.d.ts +14 -0
- package/dist/core/tree-sitter/csharp-preproc-normalizer.js +261 -0
- package/dist/core/tree-sitter/parser-loader.d.ts +10 -0
- package/dist/core/tree-sitter/parser-loader.js +19 -0
- package/dist/core/unity/doc-contract.test.d.ts +1 -0
- package/dist/core/unity/doc-contract.test.js +30 -0
- package/dist/core/unity/prefab-source-scan.d.ts +25 -0
- package/dist/core/unity/prefab-source-scan.js +152 -0
- package/dist/core/unity/prefab-source-scan.test.d.ts +1 -0
- package/dist/core/unity/prefab-source-scan.test.js +70 -0
- package/dist/core/unity/scan-context.d.ts +12 -0
- package/dist/core/unity/scan-context.js +50 -2
- package/dist/core/unity/scan-context.test.js +74 -0
- package/dist/mcp/local/agent-safe-response.d.ts +10 -0
- package/dist/mcp/local/agent-safe-response.js +639 -0
- package/dist/mcp/local/derived-process-reader.js +1 -1
- package/dist/mcp/local/local-backend.d.ts +18 -1
- package/dist/mcp/local/local-backend.js +319 -125
- package/dist/mcp/local/process-confidence.d.ts +1 -2
- package/dist/mcp/local/process-confidence.js +0 -3
- package/dist/mcp/local/process-confidence.test.js +4 -2
- package/dist/mcp/local/process-evidence.d.ts +1 -8
- package/dist/mcp/local/process-evidence.js +1 -23
- package/dist/mcp/local/process-evidence.test.js +2 -16
- package/dist/mcp/local/process-ref.d.ts +1 -1
- package/dist/mcp/local/runtime-chain-closure-evaluator.d.ts +33 -0
- package/dist/mcp/local/runtime-chain-closure-evaluator.js +273 -0
- package/dist/mcp/local/runtime-chain-graph-candidates.d.ts +23 -0
- package/dist/mcp/local/runtime-chain-graph-candidates.js +131 -0
- package/dist/mcp/local/runtime-chain-verify.d.ts +1 -1
- package/dist/mcp/local/runtime-chain-verify.js +149 -138
- package/dist/mcp/local/runtime-chain-verify.test.js +126 -68
- package/dist/mcp/local/runtime-claim-rule-registry.d.ts +4 -0
- package/dist/mcp/local/runtime-claim-rule-registry.js +4 -0
- package/dist/mcp/local/runtime-claim-rule-registry.test.js +37 -4
- package/dist/mcp/local/runtime-claim.d.ts +11 -0
- package/dist/mcp/local/runtime-claim.js +28 -0
- package/dist/mcp/local/unity-evidence-view.d.ts +1 -1
- package/dist/mcp/local/unity-evidence-view.js +1 -1
- package/dist/mcp/local/unity-evidence-view.test.js +22 -0
- package/dist/mcp/tools.js +51 -21
- package/dist/rule-lab/analyze.d.ts +2 -1
- package/dist/rule-lab/analyze.js +94 -59
- package/dist/rule-lab/analyze.test.js +238 -20
- package/dist/rule-lab/curate.d.ts +2 -1
- package/dist/rule-lab/curate.js +24 -3
- package/dist/rule-lab/curate.test.js +65 -0
- package/dist/rule-lab/curation-input-builder.d.ts +45 -0
- package/dist/rule-lab/curation-input-builder.js +133 -0
- package/dist/rule-lab/promote.js +80 -7
- package/dist/rule-lab/promote.test.js +150 -0
- package/dist/rule-lab/review-pack.d.ts +3 -0
- package/dist/rule-lab/review-pack.js +41 -1
- package/dist/rule-lab/review-pack.test.js +67 -0
- package/dist/rule-lab/types.d.ts +29 -0
- package/dist/types/pipeline.d.ts +16 -0
- package/package.json +14 -13
- package/scripts/check-sync-manifest-traceability.mjs +203 -0
- package/scripts/run-node-tests.mjs +61 -0
- package/scripts/tree-sitter-audit-classify.mjs +172 -0
- package/skills/_shared/unity-rule-authoring-contract.md +64 -0
- package/skills/_shared/unity-runtime-process-contract.md +16 -0
- package/skills/gitnexus-cli.md +44 -4
- package/skills/gitnexus-debugging.md +9 -0
- package/skills/gitnexus-exploring.md +66 -18
- package/skills/gitnexus-guide.md +42 -3
- package/skills/gitnexus-impact-analysis.md +8 -0
- package/skills/gitnexus-pr-review.md +8 -0
- package/skills/gitnexus-refactoring.md +8 -0
- package/skills/gitnexus-unity-rule-gen.md +66 -312
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type RuntimeStatus = 'verified_full' | 'verified_partial' | 'failed';
|
|
2
|
+
type RuntimeEvidenceLevel = 'verified_chain' | 'verified_segment' | 'clue' | 'none';
|
|
3
|
+
export interface RuntimePocCase {
|
|
4
|
+
case_id: string;
|
|
5
|
+
query_text: string;
|
|
6
|
+
symbol_name?: string;
|
|
7
|
+
resource_seed_path?: string;
|
|
8
|
+
mapped_seed_targets?: string[];
|
|
9
|
+
baseline: {
|
|
10
|
+
status: RuntimeStatus;
|
|
11
|
+
evidence_level: RuntimeEvidenceLevel;
|
|
12
|
+
reason?: string;
|
|
13
|
+
};
|
|
14
|
+
graph_only: {
|
|
15
|
+
status: RuntimeStatus;
|
|
16
|
+
evidence_level: RuntimeEvidenceLevel;
|
|
17
|
+
reason?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface RuntimePocBenchmarkResult {
|
|
21
|
+
comparisonPath: string;
|
|
22
|
+
summaryPath: string;
|
|
23
|
+
provenanceArtifactPath: string;
|
|
24
|
+
provenanceIndexPath: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function runRuntimePocBenchmark(input: {
|
|
27
|
+
repo: string;
|
|
28
|
+
reportDir: string;
|
|
29
|
+
casesPath?: string;
|
|
30
|
+
}): Promise<RuntimePocBenchmarkResult>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { writeRuntimeProvenanceArtifact, } from './provenance-artifact.js';
|
|
4
|
+
function toIsoStamp(date = new Date()) {
|
|
5
|
+
return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
6
|
+
}
|
|
7
|
+
function normalizeStatus(value) {
|
|
8
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
9
|
+
if (normalized === 'verified_full')
|
|
10
|
+
return 'verified_full';
|
|
11
|
+
if (normalized === 'verified_partial')
|
|
12
|
+
return 'verified_partial';
|
|
13
|
+
return 'failed';
|
|
14
|
+
}
|
|
15
|
+
function normalizeEvidence(value) {
|
|
16
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
17
|
+
if (normalized === 'verified_chain')
|
|
18
|
+
return 'verified_chain';
|
|
19
|
+
if (normalized === 'verified_segment')
|
|
20
|
+
return 'verified_segment';
|
|
21
|
+
if (normalized === 'clue')
|
|
22
|
+
return 'clue';
|
|
23
|
+
return 'none';
|
|
24
|
+
}
|
|
25
|
+
function classifyFailureBucket(input) {
|
|
26
|
+
if (normalizeStatus(input.graph_only.status) !== 'failed')
|
|
27
|
+
return 'none';
|
|
28
|
+
const reason = String(input.graph_only.reason || '').trim().toLowerCase();
|
|
29
|
+
if (reason.includes('anchor'))
|
|
30
|
+
return 'anchor_gap';
|
|
31
|
+
if (reason.includes('bind') || reason.includes('guid'))
|
|
32
|
+
return 'bind_gap';
|
|
33
|
+
if (reason.includes('bridge') || reason.includes('loader'))
|
|
34
|
+
return 'bridge_gap';
|
|
35
|
+
if (reason.includes('runtime'))
|
|
36
|
+
return 'runtime_gap';
|
|
37
|
+
if (reason.includes('policy') || reason.includes('precision'))
|
|
38
|
+
return 'precision_penalty';
|
|
39
|
+
return 'unknown_gap';
|
|
40
|
+
}
|
|
41
|
+
function buildComparisonRows(cases) {
|
|
42
|
+
return cases.map((item) => {
|
|
43
|
+
const baselineStatus = normalizeStatus(item.baseline.status);
|
|
44
|
+
const graphStatus = normalizeStatus(item.graph_only.status);
|
|
45
|
+
const failureBucket = classifyFailureBucket(item);
|
|
46
|
+
return {
|
|
47
|
+
case_id: String(item.case_id || '').trim(),
|
|
48
|
+
baseline_status: baselineStatus,
|
|
49
|
+
graph_only_status: graphStatus,
|
|
50
|
+
baseline_evidence_level: normalizeEvidence(item.baseline.evidence_level),
|
|
51
|
+
graph_only_evidence_level: normalizeEvidence(item.graph_only.evidence_level),
|
|
52
|
+
verified_full_false_positive: baselineStatus !== 'verified_full' && graphStatus === 'verified_full',
|
|
53
|
+
regression: baselineStatus === 'verified_full' && graphStatus !== 'verified_full',
|
|
54
|
+
failure_bucket: graphStatus === 'failed' ? failureBucket : 'none',
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function rate(count, total) {
|
|
59
|
+
if (total <= 0)
|
|
60
|
+
return 0;
|
|
61
|
+
return Number((count / total).toFixed(6));
|
|
62
|
+
}
|
|
63
|
+
function toMarkdown(report) {
|
|
64
|
+
return [
|
|
65
|
+
'# Runtime PoC Comparison',
|
|
66
|
+
'',
|
|
67
|
+
`- Generated At: ${report.generated_at}`,
|
|
68
|
+
`- Repo: ${report.repo}`,
|
|
69
|
+
`- Total Cases: ${report.summary.total_cases}`,
|
|
70
|
+
`- verified_full_false_positive_rate: ${report.summary.verified_full_false_positive_rate}`,
|
|
71
|
+
`- regression_count: ${report.summary.regression_count}`,
|
|
72
|
+
`- graph_failed_count: ${report.summary.graph_failed_count}`,
|
|
73
|
+
'',
|
|
74
|
+
'## Rows',
|
|
75
|
+
'',
|
|
76
|
+
'| case_id | baseline_status | graph_only_status | false_positive | regression | failure_bucket |',
|
|
77
|
+
'| --- | --- | --- | --- | --- | --- |',
|
|
78
|
+
...report.comparison_rows.map((row) => (`| ${row.case_id} | ${row.baseline_status} | ${row.graph_only_status} | ${row.verified_full_false_positive} | ${row.regression} | ${row.failure_bucket} |`)),
|
|
79
|
+
'',
|
|
80
|
+
].join('\n');
|
|
81
|
+
}
|
|
82
|
+
async function loadCases(casesPath) {
|
|
83
|
+
if (!casesPath) {
|
|
84
|
+
return [
|
|
85
|
+
{
|
|
86
|
+
case_id: 'default-case-1',
|
|
87
|
+
query_text: 'Reload GunGraph',
|
|
88
|
+
symbol_name: 'GunGraph',
|
|
89
|
+
resource_seed_path: 'Assets/NEON/DataAssets/weapon.asset',
|
|
90
|
+
mapped_seed_targets: ['Assets/NEON/Graphs/weapon_graph.asset'],
|
|
91
|
+
baseline: { status: 'verified_full', evidence_level: 'verified_chain' },
|
|
92
|
+
graph_only: { status: 'verified_full', evidence_level: 'verified_chain' },
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
case_id: 'default-case-2',
|
|
96
|
+
query_text: 'Reload WeaponPowerUp',
|
|
97
|
+
symbol_name: 'WeaponPowerUp',
|
|
98
|
+
resource_seed_path: 'Assets/NEON/DataAssets/orb.asset',
|
|
99
|
+
mapped_seed_targets: ['Assets/NEON/Graphs/global.asset'],
|
|
100
|
+
baseline: { status: 'failed', evidence_level: 'none', reason: 'rule_not_matched' },
|
|
101
|
+
graph_only: { status: 'failed', evidence_level: 'none', reason: 'anchor_gap' },
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
const raw = await fs.readFile(path.resolve(casesPath), 'utf-8');
|
|
106
|
+
const parsed = JSON.parse(raw);
|
|
107
|
+
if (!Array.isArray(parsed)) {
|
|
108
|
+
throw new Error('runtime-poc cases file must be a JSON array');
|
|
109
|
+
}
|
|
110
|
+
return parsed;
|
|
111
|
+
}
|
|
112
|
+
function toProvenanceRecords(cases) {
|
|
113
|
+
return cases.map((item) => ({
|
|
114
|
+
scenario_id: String(item.case_id || '').trim(),
|
|
115
|
+
query_text: String(item.query_text || '').trim(),
|
|
116
|
+
...(String(item.symbol_name || '').trim() ? { symbol_name: String(item.symbol_name).trim() } : {}),
|
|
117
|
+
...(String(item.resource_seed_path || '').trim()
|
|
118
|
+
? { resource_seed_path: String(item.resource_seed_path).trim() }
|
|
119
|
+
: {}),
|
|
120
|
+
mapped_seed_targets: Array.isArray(item.mapped_seed_targets) ? item.mapped_seed_targets : [],
|
|
121
|
+
runtime_claim: {
|
|
122
|
+
status: normalizeStatus(item.graph_only.status),
|
|
123
|
+
evidence_level: normalizeEvidence(item.graph_only.evidence_level),
|
|
124
|
+
...(String(item.graph_only.reason || '').trim() ? { reason: String(item.graph_only.reason).trim() } : {}),
|
|
125
|
+
},
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
export async function runRuntimePocBenchmark(input) {
|
|
129
|
+
const reportDir = path.resolve(input.reportDir);
|
|
130
|
+
await fs.mkdir(reportDir, { recursive: true });
|
|
131
|
+
const cases = await loadCases(input.casesPath);
|
|
132
|
+
const rows = buildComparisonRows(cases);
|
|
133
|
+
const falsePositiveCount = rows.filter((row) => row.verified_full_false_positive).length;
|
|
134
|
+
const regressionCount = rows.filter((row) => row.regression).length;
|
|
135
|
+
const graphFailedCount = rows.filter((row) => row.graph_only_status === 'failed').length;
|
|
136
|
+
const report = {
|
|
137
|
+
generated_at: toIsoStamp(),
|
|
138
|
+
repo: String(input.repo || '').trim(),
|
|
139
|
+
comparison_rows: rows,
|
|
140
|
+
summary: {
|
|
141
|
+
total_cases: rows.length,
|
|
142
|
+
verified_full_false_positive_count: falsePositiveCount,
|
|
143
|
+
verified_full_false_positive_rate: rate(falsePositiveCount, rows.length),
|
|
144
|
+
regression_count: regressionCount,
|
|
145
|
+
graph_failed_count: graphFailedCount,
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
const comparisonPath = path.join(reportDir, 'runtime-poc-comparison.json');
|
|
149
|
+
await fs.writeFile(comparisonPath, `${JSON.stringify(report, null, 2)}\n`, 'utf-8');
|
|
150
|
+
const summaryPath = path.join(reportDir, 'runtime-poc-summary.md');
|
|
151
|
+
await fs.writeFile(summaryPath, `${toMarkdown(report)}\n`, 'utf-8');
|
|
152
|
+
const provenance = await writeRuntimeProvenanceArtifact({
|
|
153
|
+
reportDir,
|
|
154
|
+
repo: report.repo,
|
|
155
|
+
records: toProvenanceRecords(cases),
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
comparisonPath,
|
|
159
|
+
summaryPath,
|
|
160
|
+
provenanceArtifactPath: provenance.artifactPath,
|
|
161
|
+
provenanceIndexPath: provenance.indexPath,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
@@ -39,6 +39,14 @@ export interface HydrationPolicyRepeatabilityReport {
|
|
|
39
39
|
requiresArray: boolean;
|
|
40
40
|
populatedWhenIncomplete: boolean;
|
|
41
41
|
};
|
|
42
|
+
semantic_contract: {
|
|
43
|
+
coreAdjustedDelta: {
|
|
44
|
+
strictFallbackRuns: number;
|
|
45
|
+
strictFallbackAdjustedRuns: number;
|
|
46
|
+
nonStrictAdjustedRuns: number;
|
|
47
|
+
};
|
|
48
|
+
downgradeOnlyWhenStrictFallback: boolean;
|
|
49
|
+
};
|
|
42
50
|
contractCompatibility: {
|
|
43
51
|
needsParityRetryRetained: boolean;
|
|
44
52
|
};
|
|
@@ -22,6 +22,12 @@ function snapshotFromResponse(out) {
|
|
|
22
22
|
return {
|
|
23
23
|
status: String(out?.runtime_claim?.status || 'unknown'),
|
|
24
24
|
evidence_level: String(out?.runtime_claim?.evidence_level || 'none'),
|
|
25
|
+
verification_core_status: String(out?.runtime_claim?.verification_core_status || 'unknown'),
|
|
26
|
+
verification_core_evidence_level: String(out?.runtime_claim?.verification_core_evidence_level || 'none'),
|
|
27
|
+
policy_adjusted: Boolean(out?.runtime_claim?.policy_adjusted),
|
|
28
|
+
policy_adjust_reason: out?.runtime_claim?.policy_adjust_reason
|
|
29
|
+
? String(out.runtime_claim.policy_adjust_reason)
|
|
30
|
+
: undefined,
|
|
25
31
|
reason: out?.runtime_claim?.reason ? String(out.runtime_claim.reason) : undefined,
|
|
26
32
|
fallbackToCompact: Boolean(out?.hydrationMeta?.fallbackToCompact),
|
|
27
33
|
};
|
|
@@ -100,11 +106,18 @@ export async function buildHydrationPolicyRepeatabilityReport(input) {
|
|
|
100
106
|
const balancedConsistency = classifyConsistency(snapshotsByPolicy.get('balanced') || []);
|
|
101
107
|
const strictConsistency = classifyConsistency(snapshotsByPolicy.get('strict') || []);
|
|
102
108
|
const strictRows = snapshotsByPolicy.get('strict') || [];
|
|
109
|
+
const fastRows = snapshotsByPolicy.get('fast') || [];
|
|
110
|
+
const balancedRows = snapshotsByPolicy.get('balanced') || [];
|
|
103
111
|
const strictFallbackDowngraded = strictRows.every((row) => {
|
|
104
112
|
if (!row.fallbackToCompact)
|
|
105
113
|
return true;
|
|
106
114
|
return row.status === 'verified_partial' && row.evidence_level === 'verified_segment';
|
|
107
115
|
});
|
|
116
|
+
const strictFallbackRuns = strictRows.filter((row) => row.fallbackToCompact).length;
|
|
117
|
+
const strictFallbackAdjustedRuns = strictRows.filter((row) => row.fallbackToCompact && row.policy_adjusted).length;
|
|
118
|
+
const nonStrictAdjustedRuns = [...fastRows, ...balancedRows].filter((row) => row.policy_adjusted).length;
|
|
119
|
+
const downgradeOnlyWhenStrictFallback = nonStrictAdjustedRuns === 0
|
|
120
|
+
&& strictFallbackAdjustedRuns <= strictFallbackRuns;
|
|
108
121
|
const policy_mode_matrix = {};
|
|
109
122
|
for (const policy of policies) {
|
|
110
123
|
const compactOut = await callPolicyProbe({
|
|
@@ -155,6 +168,14 @@ export async function buildHydrationPolicyRepeatabilityReport(input) {
|
|
|
155
168
|
requiresArray,
|
|
156
169
|
populatedWhenIncomplete,
|
|
157
170
|
},
|
|
171
|
+
semantic_contract: {
|
|
172
|
+
coreAdjustedDelta: {
|
|
173
|
+
strictFallbackRuns,
|
|
174
|
+
strictFallbackAdjustedRuns,
|
|
175
|
+
nonStrictAdjustedRuns,
|
|
176
|
+
},
|
|
177
|
+
downgradeOnlyWhenStrictFallback,
|
|
178
|
+
},
|
|
158
179
|
contractCompatibility: {
|
|
159
180
|
needsParityRetryRetained,
|
|
160
181
|
},
|
|
@@ -1,58 +1,62 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import {
|
|
4
|
+
import { verifyRuntimeClaimOnDemand } from '../../mcp/local/runtime-chain-verify.js';
|
|
5
|
+
function makeSymbolOnlyExecutor(symbolName, filePath) {
|
|
6
|
+
return async (query, params) => {
|
|
7
|
+
if (!String(query || '').includes('WHERE n.name IN $symbolNames')) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
const names = Array.isArray(params?.symbolNames) ? params?.symbolNames : [];
|
|
11
|
+
if (!names.includes(symbolName))
|
|
12
|
+
return [];
|
|
13
|
+
return [{
|
|
14
|
+
id: `Class:${filePath}:${symbolName}`,
|
|
15
|
+
name: symbolName,
|
|
16
|
+
type: 'Class',
|
|
17
|
+
filePath,
|
|
18
|
+
startLine: 1,
|
|
19
|
+
}];
|
|
20
|
+
};
|
|
21
|
+
}
|
|
5
22
|
export async function buildPhase2RuntimeClaimAcceptanceReport(input) {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
runtime_chain_verify: 'on-demand',
|
|
23
|
+
const repoPath = path.resolve('.');
|
|
24
|
+
const verificationFailedClaim = await verifyRuntimeClaimOnDemand({
|
|
25
|
+
repoPath,
|
|
26
|
+
queryText: 'Reload',
|
|
27
|
+
symbolName: 'ReloadBase',
|
|
28
|
+
symbolFilePath: 'Assets/NEON/Code/Game/Graph/Nodes/Reloads/ReloadBase.cs',
|
|
29
|
+
resourceSeedPath: 'Assets/Rules/reload.asset',
|
|
30
|
+
resourceBindings: [{ resourcePath: 'Assets/Rules/reload.asset' }],
|
|
31
|
+
executeParameterized: makeSymbolOnlyExecutor('ReloadBase', 'Assets/NEON/Code/Game/Graph/Nodes/Reloads/ReloadBase.cs'),
|
|
16
32
|
});
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
33
|
+
const evidenceMissingClaim = await verifyRuntimeClaimOnDemand({
|
|
34
|
+
repoPath,
|
|
35
|
+
queryText: 'Reload',
|
|
36
|
+
symbolName: 'ReloadBase',
|
|
37
|
+
symbolFilePath: 'Assets/NEON/Code/Game/Graph/Nodes/Reloads/ReloadBase.cs',
|
|
38
|
+
resourceSeedPath: 'Assets/Rules/reload.asset',
|
|
39
|
+
resourceBindings: [{ resourcePath: 'Assets/Rules/reload.asset' }],
|
|
40
|
+
minimumEvidenceSatisfied: false,
|
|
41
|
+
executeParameterized: makeSymbolOnlyExecutor('ReloadBase', 'Assets/NEON/Code/Game/Graph/Nodes/Reloads/ReloadBase.cs'),
|
|
25
42
|
});
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
const unmatchedClaim = await verifyRuntimeClaimOnDemand({
|
|
44
|
+
repoPath,
|
|
45
|
+
queryText: 'UnrelatedUnityChain',
|
|
46
|
+
resourceBindings: [],
|
|
47
|
+
executeParameterized: async () => [],
|
|
31
48
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
gateDisabled = await backend.callTool('query', {
|
|
36
|
-
repo: input.repoAlias,
|
|
37
|
-
query: 'Reload',
|
|
38
|
-
unity_resources: 'on',
|
|
39
|
-
runtime_chain_verify: 'off',
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
finally {
|
|
43
|
-
}
|
|
44
|
-
const claim = matched.runtime_claim || {};
|
|
49
|
+
const verificationFailedReason = String(verificationFailedClaim.reason || 'rule_matched_but_verification_failed');
|
|
50
|
+
const claim = verificationFailedClaim;
|
|
45
51
|
const requiredReasons = [
|
|
46
52
|
'rule_not_matched',
|
|
47
53
|
'rule_matched_but_evidence_missing',
|
|
48
54
|
'rule_matched_but_verification_failed',
|
|
49
|
-
'gate_disabled',
|
|
50
55
|
];
|
|
51
56
|
const reasons = [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
gateDisabled.runtime_claim?.reason,
|
|
57
|
+
verificationFailedReason,
|
|
58
|
+
evidenceMissingClaim.reason,
|
|
59
|
+
unmatchedClaim.reason,
|
|
56
60
|
]
|
|
57
61
|
.filter(Boolean)
|
|
58
62
|
.map((reason) => String(reason));
|
|
@@ -75,20 +79,18 @@ export async function buildPhase2RuntimeClaimAcceptanceReport(input) {
|
|
|
75
79
|
samples: {
|
|
76
80
|
matched_status: claim.status,
|
|
77
81
|
matched_reason: claim.reason,
|
|
78
|
-
evidence_missing_reason:
|
|
79
|
-
verification_failed_reason:
|
|
80
|
-
unmatched_reason:
|
|
81
|
-
gate_disabled_reason: gateDisabled.runtime_claim?.reason,
|
|
82
|
+
evidence_missing_reason: evidenceMissingClaim.reason,
|
|
83
|
+
verification_failed_reason: verificationFailedReason,
|
|
84
|
+
unmatched_reason: unmatchedClaim.reason,
|
|
82
85
|
},
|
|
83
86
|
reproduction_commands: {
|
|
84
|
-
rule_matched_but_verification_failed:
|
|
85
|
-
rule_matched_but_evidence_missing:
|
|
86
|
-
rule_not_matched:
|
|
87
|
-
gate_disabled: `gitnexus query --repo ${input.repoAlias} --runtime-chain-verify off --unity-resources on "Reload"`,
|
|
87
|
+
rule_matched_but_verification_failed: 'gitnexus query --runtime-chain-verify on-demand --unity-resources on "Reload"',
|
|
88
|
+
rule_matched_but_evidence_missing: 'gitnexus query --runtime-chain-verify on-demand --unity-resources on --unity-evidence-mode summary --max-bindings 1 --max-reference-fields 1 "Reload"',
|
|
89
|
+
rule_not_matched: 'gitnexus query --runtime-chain-verify on-demand --unity-resources on "UnrelatedUnityChain"',
|
|
88
90
|
},
|
|
89
91
|
};
|
|
90
92
|
if (!coverage_pass) {
|
|
91
|
-
throw new Error(`phase2 failure classification coverage is incomplete (${failure_classification_coverage.length}/
|
|
93
|
+
throw new Error(`phase2 failure classification coverage is incomplete (${failure_classification_coverage.length}/3). Missing: ${failure_classification_missing.join(', ')}`);
|
|
92
94
|
}
|
|
93
95
|
return report;
|
|
94
96
|
}
|
|
@@ -12,5 +12,4 @@ test('phase2 runtime_claim acceptance report tracks contract + failure classific
|
|
|
12
12
|
assert.equal(report.failure_classification_coverage.includes('rule_not_matched'), true);
|
|
13
13
|
assert.equal(report.failure_classification_coverage.includes('rule_matched_but_evidence_missing'), true);
|
|
14
14
|
assert.equal(report.failure_classification_coverage.includes('rule_matched_but_verification_failed'), true);
|
|
15
|
-
assert.equal(report.failure_classification_coverage.includes('gate_disabled'), true);
|
|
16
15
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { discoverRuleLabRun } from '../../rule-lab/discover.js';
|
|
4
3
|
import { analyzeRuleLabSlice } from '../../rule-lab/analyze.js';
|
|
5
4
|
import { buildReviewPack } from '../../rule-lab/review-pack.js';
|
|
6
5
|
import { curateRuleLabSlice } from '../../rule-lab/curate.js';
|
|
@@ -8,8 +7,6 @@ import { promoteCuratedRules } from '../../rule-lab/promote.js';
|
|
|
8
7
|
import { runRuleLabRegress } from '../../rule-lab/regress.js';
|
|
9
8
|
function commandFor(stage, input) {
|
|
10
9
|
switch (stage) {
|
|
11
|
-
case 'discover':
|
|
12
|
-
return 'gitnexus rule-lab discover --scope full';
|
|
13
10
|
case 'analyze':
|
|
14
11
|
return `gitnexus rule-lab analyze --run-id ${input.runId} --slice-id ${input.sliceId}`;
|
|
15
12
|
case 'review-pack':
|
|
@@ -27,11 +24,69 @@ function commandFor(stage, input) {
|
|
|
27
24
|
async function mustExist(filePath) {
|
|
28
25
|
await fs.access(filePath);
|
|
29
26
|
}
|
|
27
|
+
async function bootstrapReducedRuleLabRun(input) {
|
|
28
|
+
const normalizedSeed = String(input.seed || Date.now())
|
|
29
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
30
|
+
.toLowerCase();
|
|
31
|
+
const runId = `phase5-${normalizedSeed}-${Date.now()}`;
|
|
32
|
+
const sliceId = 'slice-startup-exact-pair';
|
|
33
|
+
const runRoot = path.join(input.repoPath, '.gitnexus', 'rules', 'lab', 'runs', runId);
|
|
34
|
+
const sliceRoot = path.join(runRoot, 'slices', sliceId);
|
|
35
|
+
const manifestPath = path.join(runRoot, 'manifest.json');
|
|
36
|
+
const slicePath = path.join(sliceRoot, 'slice.json');
|
|
37
|
+
await fs.mkdir(sliceRoot, { recursive: true });
|
|
38
|
+
await fs.writeFile(manifestPath, `${JSON.stringify({
|
|
39
|
+
run_id: runId,
|
|
40
|
+
repo_path: input.repoPath,
|
|
41
|
+
scope: 'full',
|
|
42
|
+
generated_at: new Date().toISOString(),
|
|
43
|
+
slices: [
|
|
44
|
+
{
|
|
45
|
+
id: sliceId,
|
|
46
|
+
trigger_family: 'startup',
|
|
47
|
+
resource_types: ['asset'],
|
|
48
|
+
host_base_type: ['StartupNode'],
|
|
49
|
+
required_hops: ['resource', 'code_runtime'],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
stages: ['analyze'],
|
|
53
|
+
next_actions: [`gitnexus rule-lab analyze --run-id ${runId} --slice-id ${sliceId}`],
|
|
54
|
+
}, null, 2)}\n`, 'utf-8');
|
|
55
|
+
await fs.writeFile(slicePath, `${JSON.stringify({
|
|
56
|
+
id: sliceId,
|
|
57
|
+
trigger_family: 'startup',
|
|
58
|
+
resource_types: ['asset'],
|
|
59
|
+
host_base_type: ['StartupNode'],
|
|
60
|
+
required_hops: ['resource', 'code_runtime'],
|
|
61
|
+
exact_pairs: [
|
|
62
|
+
{
|
|
63
|
+
id: 'pair-startup-1',
|
|
64
|
+
binding_kind: 'method_triggers_method',
|
|
65
|
+
draft_rule_id: 'demo.startup.v1',
|
|
66
|
+
source_anchor: {
|
|
67
|
+
file: 'Assets/Rules/startup.asset',
|
|
68
|
+
line: 1,
|
|
69
|
+
symbol: 'StartupNode.Initialize',
|
|
70
|
+
},
|
|
71
|
+
target_anchor: {
|
|
72
|
+
file: 'Assets/Rules/startup.asset',
|
|
73
|
+
line: 1,
|
|
74
|
+
symbol: 'StartupNode.Bootstrap',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
}, null, 2)}\n`, 'utf-8');
|
|
79
|
+
return {
|
|
80
|
+
runId,
|
|
81
|
+
sliceId,
|
|
82
|
+
manifestPath,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
30
85
|
function buildFailureTaxonomy(runId) {
|
|
31
86
|
return [
|
|
32
87
|
{
|
|
33
88
|
code: 'rule_not_matched',
|
|
34
|
-
retry_hint: 'confirm trigger_family tokens and rerun
|
|
89
|
+
retry_hint: 'confirm trigger_family tokens and rerun analyze/promote',
|
|
35
90
|
repro_command: `gitnexus rule-lab analyze --run-id ${runId} --slice-id <slice_id>`,
|
|
36
91
|
},
|
|
37
92
|
{
|
|
@@ -70,7 +125,20 @@ function hasDslPlaceholders(text) {
|
|
|
70
125
|
return /(^|\s)(unknown|todo|tbd)(\s|$)|<[^>]+>/i.test(text);
|
|
71
126
|
}
|
|
72
127
|
async function buildAuthenticityChecks(input) {
|
|
73
|
-
const
|
|
128
|
+
const verifierPathCandidates = [
|
|
129
|
+
path.join(input.repoPath, 'gitnexus', 'src', 'mcp', 'local', 'runtime-chain-verify.ts'),
|
|
130
|
+
path.join(input.repoPath, 'src', 'mcp', 'local', 'runtime-chain-verify.ts'),
|
|
131
|
+
];
|
|
132
|
+
let verifierPath = verifierPathCandidates[0];
|
|
133
|
+
for (const candidate of verifierPathCandidates) {
|
|
134
|
+
try {
|
|
135
|
+
await fs.access(candidate);
|
|
136
|
+
verifierPath = candidate;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
}
|
|
141
|
+
}
|
|
74
142
|
const verifierRaw = await fs.readFile(verifierPath, 'utf-8');
|
|
75
143
|
const blockedSymbols = [
|
|
76
144
|
'RESOURCE_ASSET_PATH',
|
|
@@ -98,17 +166,12 @@ async function buildAuthenticityChecks(input) {
|
|
|
98
166
|
export async function buildPhase5RuleLabAcceptanceReport(input) {
|
|
99
167
|
const repoPath = path.resolve(input.repoPath || process.cwd());
|
|
100
168
|
const stageCoverage = [];
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
command: commandFor('discover', {}),
|
|
105
|
-
status: 'passed',
|
|
169
|
+
const bootstrapped = await bootstrapReducedRuleLabRun({
|
|
170
|
+
repoPath,
|
|
171
|
+
seed: input.seed || 'phase5-acceptance',
|
|
106
172
|
});
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
const sliceId = discover.manifest.slices[0].id;
|
|
111
|
-
const runId = discover.runId;
|
|
173
|
+
const sliceId = bootstrapped.sliceId;
|
|
174
|
+
const runId = bootstrapped.runId;
|
|
112
175
|
const analyze = await analyzeRuleLabSlice({ repoPath, runId, sliceId });
|
|
113
176
|
stageCoverage.push({
|
|
114
177
|
stage: 'analyze',
|
|
@@ -122,6 +185,7 @@ export async function buildPhase5RuleLabAcceptanceReport(input) {
|
|
|
122
185
|
status: 'passed',
|
|
123
186
|
});
|
|
124
187
|
const firstCandidate = analyze.candidates[0];
|
|
188
|
+
const promotedRuleId = `demo.startup.${runId}.v1`;
|
|
125
189
|
const curationInputPath = path.join(repoPath, '.gitnexus', 'rules', 'lab', 'runs', runId, 'slices', sliceId, 'curation-input.json');
|
|
126
190
|
await fs.writeFile(curationInputPath, `${JSON.stringify({
|
|
127
191
|
run_id: runId,
|
|
@@ -129,7 +193,7 @@ export async function buildPhase5RuleLabAcceptanceReport(input) {
|
|
|
129
193
|
curated: [
|
|
130
194
|
{
|
|
131
195
|
id: firstCandidate.id,
|
|
132
|
-
rule_id:
|
|
196
|
+
rule_id: promotedRuleId,
|
|
133
197
|
title: 'startup startup graph',
|
|
134
198
|
match: {
|
|
135
199
|
trigger_tokens: ['startup'],
|
|
@@ -195,7 +259,7 @@ export async function buildPhase5RuleLabAcceptanceReport(input) {
|
|
|
195
259
|
retry_hint: regress.pass ? undefined : regress.failures.join(','),
|
|
196
260
|
});
|
|
197
261
|
const artifactPaths = {
|
|
198
|
-
manifest:
|
|
262
|
+
manifest: bootstrapped.manifestPath,
|
|
199
263
|
candidates: analyze.paths.candidatesPath,
|
|
200
264
|
review_cards: reviewPack.paths.reviewCardsPath,
|
|
201
265
|
curation_input: curationInputPath,
|
|
@@ -240,7 +304,7 @@ export async function runPhase5RuleLabGate(input) {
|
|
|
240
304
|
try {
|
|
241
305
|
const raw = await fs.readFile(reportPath, 'utf-8');
|
|
242
306
|
const report = JSON.parse(raw);
|
|
243
|
-
if (!Array.isArray(report.stage_coverage) || report.stage_coverage.length !==
|
|
307
|
+
if (!Array.isArray(report.stage_coverage) || report.stage_coverage.length !== 5) {
|
|
244
308
|
return { pass: false, reason: 'stage_coverage_incomplete' };
|
|
245
309
|
}
|
|
246
310
|
if (typeof report.metrics?.precision !== 'number' || typeof report.metrics?.coverage !== 'number') {
|
|
@@ -9,7 +9,7 @@ const { test: rawTest } = process.env.VITEST
|
|
|
9
9
|
const test = rawTest;
|
|
10
10
|
test('phase5 rule-lab acceptance runner emits complete stage coverage', async () => {
|
|
11
11
|
const report = await buildPhase5RuleLabAcceptanceReport({ repoAlias: 'GitNexus' });
|
|
12
|
-
assert.equal(report.stage_coverage.length,
|
|
12
|
+
assert.equal(report.stage_coverage.length, 5);
|
|
13
13
|
assert.equal(typeof report.metrics.precision, 'number');
|
|
14
14
|
});
|
|
15
15
|
test('phase5 gate fails when required artifacts are missing', async () => {
|
|
@@ -22,7 +22,6 @@ test('phase5 gate fails when anti-hardcode scan or dsl lint fails', async () =>
|
|
|
22
22
|
const reportPath = path.join(tmpDir, 'report.json');
|
|
23
23
|
await fs.writeFile(reportPath, JSON.stringify({
|
|
24
24
|
stage_coverage: [
|
|
25
|
-
{ stage: 'discover', status: 'passed' },
|
|
26
25
|
{ stage: 'analyze', status: 'passed' },
|
|
27
26
|
{ stage: 'review-pack', status: 'passed' },
|
|
28
27
|
{ stage: 'curate', status: 'passed' },
|
|
@@ -191,16 +191,17 @@ function assertScenario(scenario, contextOnOutput, deepDiveExecutions, contextUn
|
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
193
|
async function invokeTool(runner, tool, input) {
|
|
194
|
+
const params = withLegacyFullProfile(tool, input);
|
|
194
195
|
if (tool === 'query') {
|
|
195
|
-
return runner.query(
|
|
196
|
+
return runner.query(params);
|
|
196
197
|
}
|
|
197
198
|
if (tool === 'context') {
|
|
198
|
-
return runner.context(
|
|
199
|
+
return runner.context(params);
|
|
199
200
|
}
|
|
200
201
|
if (tool === 'impact') {
|
|
201
|
-
return runner.impact(
|
|
202
|
+
return runner.impact(params);
|
|
202
203
|
}
|
|
203
|
-
return runner.cypher(
|
|
204
|
+
return runner.cypher(params);
|
|
204
205
|
}
|
|
205
206
|
function selectDisambiguationUid(symbol, output) {
|
|
206
207
|
const expectedFile = `${symbol}.cs`.toLowerCase();
|
|
@@ -222,20 +223,21 @@ function selectDisambiguationUid(symbol, output) {
|
|
|
222
223
|
return undefined;
|
|
223
224
|
}
|
|
224
225
|
async function runContextWithDisambiguation(runner, scenario, input) {
|
|
225
|
-
const
|
|
226
|
+
const normalizedInput = withLegacyFullProfile('context', input);
|
|
227
|
+
const first = await runner.context(normalizedInput);
|
|
226
228
|
if (first?.status !== 'ambiguous') {
|
|
227
229
|
return first;
|
|
228
230
|
}
|
|
229
231
|
const hint = typeof scenario.contextFileHint === 'string' ? scenario.contextFileHint.trim() : '';
|
|
230
232
|
if (hint) {
|
|
231
|
-
const hinted = await runner.context({ ...input, file_path: hint });
|
|
233
|
+
const hinted = await runner.context(withLegacyFullProfile('context', { ...input, file_path: hint }));
|
|
232
234
|
if (hinted?.status !== 'ambiguous') {
|
|
233
235
|
return hinted;
|
|
234
236
|
}
|
|
235
237
|
}
|
|
236
238
|
const uid = selectDisambiguationUid(scenario.symbol, first);
|
|
237
239
|
if (uid) {
|
|
238
|
-
return runner.context({ ...input, uid });
|
|
240
|
+
return runner.context(withLegacyFullProfile('context', { ...input, uid }));
|
|
239
241
|
}
|
|
240
242
|
return first;
|
|
241
243
|
}
|
|
@@ -276,3 +278,9 @@ export async function runSymbolScenario(runner, scenario, repo) {
|
|
|
276
278
|
assertions: assertScenario(scenario, contextOn, deepDiveExecutions, contextUnityHydration),
|
|
277
279
|
};
|
|
278
280
|
}
|
|
281
|
+
function withLegacyFullProfile(tool, input) {
|
|
282
|
+
if ((tool === 'query' || tool === 'context') && !('response_profile' in input)) {
|
|
283
|
+
return { ...input, response_profile: 'full' };
|
|
284
|
+
}
|
|
285
|
+
return input;
|
|
286
|
+
}
|