@thomasminh1995/depverdict 0.6.0-alpha.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/LICENSE +21 -0
- package/README.md +518 -0
- package/bin/depverdict.js +7 -0
- package/bin/upgradelens.js +7 -0
- package/docs/GR-01-Semantic-Grounding-Failure-Analysis.md +309 -0
- package/docs/GR-02-Versioned-Action-Evaluation-Criteria.md +187 -0
- package/docs/GR-03-Extractive-Contract-Safety-Experiment.md +242 -0
- package/docs/GR-04-Versioned-Production-Extractive-Contract.md +154 -0
- package/docs/IA-01-Repository-Usage-Discovery.md +122 -0
- package/docs/IA-02-Repository-Impact-Analysis.md +118 -0
- package/docs/IA-03-Repository-Impact-Evidence.md +160 -0
- package/docs/IA-04-CLI-Orchestration.md +235 -0
- package/docs/IA-05-Real-Provider-Validation.md +235 -0
- package/docs/IA-05-VinGrade-Validation.md +339 -0
- package/docs/MVP-01.md +48 -0
- package/docs/MVP-02-Architecture.md +536 -0
- package/docs/MVP-02-CLI-HTTP-Runtime.md +50 -0
- package/docs/MVP-02-HTTP-Lifecycle.md +37 -0
- package/docs/MVP-02-Knowledge-Manifest-Generation.md +75 -0
- package/docs/MVP-02-Knowledge-Manifest.md +279 -0
- package/docs/MVP-02-Knowledge-Research-Orchestration.md +62 -0
- package/docs/MVP-02-Knowledge-Store.md +87 -0
- package/docs/MVP-02-PyPI-Registry-Adapter.md +97 -0
- package/docs/MVP-02-Research-Planning.md +196 -0
- package/docs/MVP-02-Source-Provenance.md +81 -0
- package/docs/MVP-02-npm-Registry-Adapter.md +99 -0
- package/docs/RR-01-End-to-End-and-Real-Provider-Validation.md +393 -0
- package/docs/RR-01-RERUN-Extractive-Contract-Validation.md +566 -0
- package/docs/RR-02-Full-Product-Workflow-and-Developer-CLI-UX-Review.md +35 -0
- package/docs/RR02-FIX-01-Persistent-Qualification-Resolution.md +32 -0
- package/docs/RR02-FIX-02-Stage-aware-CLI-Progress-and-Heartbeat.md +28 -0
- package/docs/RR02-FIX-03-npm-Capture-Evidence-Exclusion.md +33 -0
- package/docs/RR02-FIX-03A-Complete-Package-Exclusion-and-Evidence-Commit.md +223 -0
- package/docs/RR02-FIX-04-Event-loop-safe-Heartbeat.md +393 -0
- package/docs/RR02-FIX-05-Materialize-Persisted-Qualification.md +207 -0
- package/docs/RR02-RERUN-CLI-Qualification-Progress-UX-and-Package-Validation.md +342 -0
- package/docs/VinGrade-MVP-02-Validation.md +480 -0
- package/docs/VinGrade-RC02-Live-Validation.md +273 -0
- package/docs/ai-capability-discovery.md +573 -0
- package/docs/ai-engineering-production-readiness.md +390 -0
- package/docs/ai-engineering-review.md +251 -0
- package/docs/ai-runtime-governance-discovery.md +754 -0
- package/docs/architecture-overview.md +78 -0
- package/docs/cli-progress.md +111 -0
- package/docs/decisions/diff-01-brand-distribution-identity.md +450 -0
- package/docs/decisions/diff-02-identity-compatibility-contract.md +274 -0
- package/docs/decisions/diff-03-repository-docs-community-migration.md +165 -0
- package/docs/decisions/diff-04-release-evidence-gap-acceptance.md +110 -0
- package/docs/discovery/mvp-05-ai-migration-planning-discovery.md +350 -0
- package/docs/gateway-runtime-discovery.md +614 -0
- package/docs/live-ai-validation.md +299 -0
- package/docs/migration-planning-qualification-resolution.md +99 -0
- package/docs/migrations/upgradelens-to-depverdict.md +97 -0
- package/docs/mp-r03-deterministic-upgrade-decision-architecture.md +135 -0
- package/docs/mp-r04-evidence-bounded-migration-handoff-architecture.md +116 -0
- package/docs/mp-r05-product-completion-and-decision-first-cli-architecture.md +162 -0
- package/docs/mvp-05-deterministic-context-runtime.md +127 -0
- package/docs/mvp-05-migration-checklist-contract.md +166 -0
- package/docs/mvp-05-migration-checklist-orchestration.md +105 -0
- package/docs/mvp-05-migration-evaluation-and-qualification.md +135 -0
- package/docs/mvp-05-provider-neutral-generator.md +79 -0
- package/docs/ollama-local-smoke-validation.md +156 -0
- package/docs/openai-compatible-runtime-discovery.md +789 -0
- package/docs/openrouter-one-dependency-validation.md +205 -0
- package/docs/oss-02-package-guard-hardening-architecture.md +131 -0
- package/docs/oss-04-public-ci-package-metadata-architecture.md +142 -0
- package/docs/package-content-policy.md +98 -0
- package/docs/releases/v0.5.0-technical-preview.md +114 -0
- package/docs/releases/v0.6.0-alpha.1-depverdict-preview.md +101 -0
- package/docs/reviews/diff-02-identity-contract-compatibility.md +413 -0
- package/docs/reviews/diff-03-repository-docs-community-migration.md +364 -0
- package/docs/reviews/diff-04-depverdict-distribution-identity-readiness-rereview.md +453 -0
- package/docs/reviews/diff-04-fix-post-rename-identity-release-remediation.md +310 -0
- package/docs/reviews/diff-05-final-preview-distribution-qualification.md +561 -0
- package/docs/reviews/mvp-05-final-product-value-workflow-rereview.md +471 -0
- package/docs/reviews/mvp-05-product-workflow-review.md +605 -0
- package/docs/reviews/oss-01-duplicate-artifact-investigation-cleanup.md +411 -0
- package/docs/reviews/oss-02-package-guard-hardening.md +303 -0
- package/docs/reviews/oss-03-community-scaffolding.md +378 -0
- package/docs/reviews/oss-04-public-ci-package-metadata.md +439 -0
- package/docs/reviews/oss-05-technical-preview-qualification.md +482 -0
- package/docs/reviews/upgradelens-vs-upgradedepdetective-source-comparison.md +355 -0
- package/docs/reviews/v0.5.0-pre-release-smoke.md +263 -0
- package/docs/reviews/v0.5.0-version-bump-release-verification.md +306 -0
- package/docs/runtime-contract-discovery.md +521 -0
- package/docs/structured-output-compatibility-report.md +100 -0
- package/docs/ts-fix-01-exact-duplicate-occurrence-target-selection-architecture.md +111 -0
- package/docs/version-analysis-architecture.md +827 -0
- package/eval/README.md +86 -0
- package/eval/datasets/generic/declared-constraint.json +59 -0
- package/eval/datasets/generic/evidence-conflict.json +73 -0
- package/eval/datasets/generic/major-breaking-release.json +66 -0
- package/eval/datasets/generic/missing-evidence.json +46 -0
- package/eval/datasets/generic/patch-release-low.json +59 -0
- package/eval/datasets/node/axios-patch-low.json +59 -0
- package/eval/datasets/node/react-major-breaking.json +66 -0
- package/eval/datasets/node/react-minor-compatibility.json +66 -0
- package/eval/datasets/python/fastapi-deprecation.json +66 -0
- package/eval/datasets/python/pydantic-major-breaking.json +66 -0
- package/eval/migration-planning/golden-dataset-v2.json +306 -0
- package/eval/migration-planning/golden-dataset.json +214 -0
- package/eval/schemas/expected-result.schema.json +88 -0
- package/eval/schemas/golden-case.schema.json +181 -0
- package/package.json +57 -0
- package/schemas/ai-scorecard.schema.json +132 -0
- package/schemas/benchmark-report.schema.json +189 -0
- package/schemas/benchmark.schema.json +55 -0
- package/schemas/capability-profile.schema.json +44 -0
- package/schemas/conformance-report.schema.json +150 -0
- package/schemas/deployment-profile.schema.json +64 -0
- package/schemas/evaluation-report.schema.json +158 -0
- package/schemas/knowledge-evidence-bundle.schema.json +150 -0
- package/schemas/knowledge-manifest.schema.json +548 -0
- package/schemas/metrics.schema.json +178 -0
- package/schemas/migration-checklist-extractive-candidate.schema.json +42 -0
- package/schemas/migration-checklist.schema.json +706 -0
- package/schemas/migration-evaluation-dataset-v2.schema.json +208 -0
- package/schemas/migration-evaluation-dataset.schema.json +204 -0
- package/schemas/migration-planning-qualification-record.schema.json +234 -0
- package/schemas/project-manifest.schema.json +308 -0
- package/schemas/qualification-record.schema.json +56 -0
- package/schemas/repository-impact-evidence.schema.json +232 -0
- package/schemas/repository-impact.schema.json +202 -0
- package/schemas/upgrade-decision.schema.json +273 -0
- package/schemas/usage-index.schema.json +179 -0
- package/schemas/version-analysis.schema.json +449 -0
- package/src/ai-runtime-debug.js +325 -0
- package/src/ai-runtime-error.js +42 -0
- package/src/ai-runtime.js +174 -0
- package/src/ai-scorecard.js +204 -0
- package/src/ai-version-analysis.js +484 -0
- package/src/artifact-root-compatibility.js +91 -0
- package/src/benchmark-report.js +111 -0
- package/src/benchmark-runner.js +191 -0
- package/src/canonical-json.js +69 -0
- package/src/cli.js +1299 -0
- package/src/conformance-report.js +158 -0
- package/src/conformance-runner.js +253 -0
- package/src/constants.js +73 -0
- package/src/cooperative-scheduler.js +79 -0
- package/src/dependencies.js +44 -0
- package/src/dependency-ai-context.js +625 -0
- package/src/detectors.js +253 -0
- package/src/discovery.js +234 -0
- package/src/ecosystem-version-adapter.js +294 -0
- package/src/environment-compatibility.js +77 -0
- package/src/evaluation-comparator.js +158 -0
- package/src/evaluation-report.js +76 -0
- package/src/evaluation-runner.js +248 -0
- package/src/evidence-source-adapter.js +472 -0
- package/src/files.js +89 -0
- package/src/governance-diagnostics.js +64 -0
- package/src/governance-loader.js +63 -0
- package/src/governance-metadata.js +346 -0
- package/src/governance-validator.js +360 -0
- package/src/http/bounded-fetch.js +278 -0
- package/src/http/cli-http-runtime.js +44 -0
- package/src/impact/input-loader.js +157 -0
- package/src/impact/matcher.js +40 -0
- package/src/impact/repository-impact.js +199 -0
- package/src/impact/runtime.js +24 -0
- package/src/impact/status.js +62 -0
- package/src/impact/writer.js +30 -0
- package/src/impact-evidence/input-loader.js +202 -0
- package/src/impact-evidence/repository-impact-evidence.js +234 -0
- package/src/impact-evidence/runtime.js +16 -0
- package/src/impact-evidence/writer.js +30 -0
- package/src/index.js +563 -0
- package/src/installed-version-baseline.js +196 -0
- package/src/knowledge-cache.js +324 -0
- package/src/knowledge-evidence-bundle.js +101 -0
- package/src/knowledge-evidence-producer.js +233 -0
- package/src/knowledge-manifest-builder.js +188 -0
- package/src/knowledge-manifest-writer.js +32 -0
- package/src/knowledge-manifest.js +255 -0
- package/src/knowledge-research.js +615 -0
- package/src/metrics-engine.js +205 -0
- package/src/migration-checklist/ai-candidate.js +320 -0
- package/src/migration-checklist/assembler.js +37 -0
- package/src/migration-checklist/context-runtime.js +828 -0
- package/src/migration-checklist/evaluation/action-criteria.js +244 -0
- package/src/migration-checklist/evaluation/comparator-v2.js +332 -0
- package/src/migration-checklist/evaluation/comparator.js +279 -0
- package/src/migration-checklist/evaluation/dataset-v2.js +227 -0
- package/src/migration-checklist/evaluation/dataset.js +336 -0
- package/src/migration-checklist/evaluation/extractive-fixtures-v2.js +148 -0
- package/src/migration-checklist/evaluation/metrics-v2.js +226 -0
- package/src/migration-checklist/evaluation/metrics.js +158 -0
- package/src/migration-checklist/evaluation/qualification-v2.js +321 -0
- package/src/migration-checklist/evaluation/qualification.js +239 -0
- package/src/migration-checklist/evaluation/runner-v2.js +294 -0
- package/src/migration-checklist/evaluation/runner.js +194 -0
- package/src/migration-checklist/evaluation/scorecard-v2.js +106 -0
- package/src/migration-checklist/evaluation/scorecard.js +86 -0
- package/src/migration-checklist/extractive-candidate.js +166 -0
- package/src/migration-checklist/extractive-prompt.js +62 -0
- package/src/migration-checklist/generator.js +702 -0
- package/src/migration-checklist/grounding-policy.js +117 -0
- package/src/migration-checklist/input-loader.js +613 -0
- package/src/migration-checklist/migration-checklist.js +635 -0
- package/src/migration-checklist/presentation.js +292 -0
- package/src/migration-checklist/progress.js +96 -0
- package/src/migration-checklist/prompt.js +83 -0
- package/src/migration-checklist/qualification-guard.js +462 -0
- package/src/migration-checklist/qualification-resolution.js +122 -0
- package/src/migration-checklist/qualification-store.js +225 -0
- package/src/migration-checklist/runtime.js +205 -0
- package/src/migration-checklist/verification.js +134 -0
- package/src/migration-checklist/writer.js +35 -0
- package/src/openai-compatible-provider.js +451 -0
- package/src/orchestration/failure-log.js +32 -0
- package/src/orchestration/pipeline.js +200 -0
- package/src/orchestration/progress-events.js +337 -0
- package/src/orchestration/progress-reporter.js +131 -0
- package/src/orchestration/text-writer.js +22 -0
- package/src/portable.js +13 -0
- package/src/product-completion.js +249 -0
- package/src/project-manifest-input.js +90 -0
- package/src/project-manifest.js +141 -0
- package/src/python-requirements.js +137 -0
- package/src/registry/npm-packument.js +256 -0
- package/src/registry/npm-registry-adapter.js +262 -0
- package/src/registry/pypi-project.js +300 -0
- package/src/registry/pypi-registry-adapter.js +235 -0
- package/src/registry/sanitize-registry-body.js +51 -0
- package/src/renderers/console.js +160 -0
- package/src/renderers/impact-presentation.js +278 -0
- package/src/renderers/markdown.js +172 -0
- package/src/research-plan.js +455 -0
- package/src/runtime-conformance.js +275 -0
- package/src/source-provenance.js +393 -0
- package/src/source-url.js +62 -0
- package/src/structured-output-schema.js +66 -0
- package/src/target-selector.js +306 -0
- package/src/upgrade-decision/input-loader.js +107 -0
- package/src/upgrade-decision/presentation.js +43 -0
- package/src/upgrade-decision/runtime.js +21 -0
- package/src/upgrade-decision/upgrade-decision.js +626 -0
- package/src/upgrade-decision/writer.js +30 -0
- package/src/usage/analyzer-registry.js +63 -0
- package/src/usage/coverage.js +116 -0
- package/src/usage/input-loader.js +139 -0
- package/src/usage/js/analyzer.js +240 -0
- package/src/usage/js/parser.js +21 -0
- package/src/usage/runtime.js +187 -0
- package/src/usage/scope.js +44 -0
- package/src/usage/source-files.js +50 -0
- package/src/usage/usage-index.js +217 -0
- package/src/usage/writer.js +31 -0
- package/src/version-analysis-loader.js +203 -0
- package/src/version-analysis-manifest.js +314 -0
- package/src/version-analysis-writer.js +30 -0
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
# LR-00A — 9Router & OpenRouter Analysis Suitability Discovery
|
|
2
|
+
|
|
3
|
+
Ngày đánh giá: 2026-07-15
|
|
4
|
+
Phạm vi: discovery kiến trúc và policy. Tài liệu này không cài gateway, không gọi model, không tạo tài khoản/API key, không sửa runtime, prompt, schema, trust layer, benchmark hay production code.
|
|
5
|
+
|
|
6
|
+
## 1. Executive Summary
|
|
7
|
+
|
|
8
|
+
UpgradeLens nên giữ kiến trúc protocol-first đã chốt ở LR-00:
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
AiRuntime
|
|
12
|
+
↓
|
|
13
|
+
OpenAI-Compatible Provider
|
|
14
|
+
↓
|
|
15
|
+
Optional Gateway
|
|
16
|
+
├── 9Router
|
|
17
|
+
└── OpenRouter
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Một OpenAI-compatible Chat Completions provider là đủ cho transport của cả 9Router và OpenRouter. Không có bằng chứng cần hai adapter vendor-specific. Khác biệt gateway chỉ nên nằm trong cấu hình endpoint, optional request headers/body extras được allowlist, routing policy và mapping execution metadata.
|
|
21
|
+
|
|
22
|
+
Quyết định vai trò:
|
|
23
|
+
|
|
24
|
+
| Runtime | Vai trò khuyến nghị | Quyết định |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| Direct Ollama | Local technical smoke và baseline local có kiểm soát | Khuyến nghị đầu tiên theo LR-00; chất lượng model vẫn phải benchmark |
|
|
27
|
+
| 9Router | OSS multi-provider development và contributor smoke tùy chọn | Khuyến nghị có điều kiện; không làm dependency/default bắt buộc |
|
|
28
|
+
| OpenRouter | Cloud model comparison và benchmark production-like | Gateway cloud chính có điều kiện; phải dùng locked route |
|
|
29
|
+
| Direct provider | Production deployment đã chọn và validation rõ | Hợp lệ khi operator chấp nhận provider, privacy và model cụ thể |
|
|
30
|
+
|
|
31
|
+
9Router chạy local, MIT, self-hostable, có `/v1/*` OpenAI-compatible, translation, provider/model aliases, combos, account fallback, quota/usage tracking và local persistence. Tuy nhiên, combo/fusion/round-robin, account rotation, capability reordering và các token-saver có thể đổi model hoặc sửa prompt/context. Source còn cho thấy `response_format.json_schema` khi dịch OpenAI sang Claude được chuyển thành chỉ dẫn trong system prompt, không phải native schema constraint. Vì vậy 9Router chỉ đủ reproducible khi dùng profile bị khóa: provider-prefixed exact model, không combo/fusion/round-robin, một account đang enable, mọi transform tắt, gateway version cố định và execution detail được thu thập.
|
|
32
|
+
|
|
33
|
+
OpenRouter có contract phù hợp benchmark hơn: model slug, `provider.only`, `allow_fallbacks: false`, `require_parameters: true`, `response_format.json_schema`, Models API `supported_parameters`, usage/cost và opt-in `openrouter_metadata` chứa actual provider/model/attempts/pipeline. `openrouter/auto`, `openrouter/free`, model fallbacks và provider fallback mặc định không phù hợp Version Analysis benchmark vì làm route thay đổi. OpenRouter vẫn là cloud processor: evidence rời máy và đi qua OpenRouter cùng upstream provider; ZDR/data policy phải được chọn rõ.
|
|
34
|
+
|
|
35
|
+
Không gateway nào được phép làm authority cho deterministic facts. `currentVersion`, `targetVersion`, dependency identity và evidence allowlist vẫn do local pipeline quyết định. Mọi model output phải qua Ajv và trust validation. MVP-04/MVP-05 chỉ được consume trusted result có route identity đã biết và đã vượt quality gate trong tài liệu này.
|
|
36
|
+
|
|
37
|
+
## 2. Why Gateway Choice Affects Version Upgrade Analysis
|
|
38
|
+
|
|
39
|
+
### 2.1 Contract hiện có
|
|
40
|
+
|
|
41
|
+
| Contract | Ranh giới liên quan gateway |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `AiRuntime` | Nhận `runId`, `contextId`, `promptVersion`, deterministic `context`, `outputSchema`; trả `output`, `provider`, `model`, `latencyMs`, optional `usage` |
|
|
44
|
+
| OpenAI-compatible architecture | Adapter map prompt/schema sang `model`, `messages`, `response_format`; gateway chỉ là endpoint tùy chọn sau adapter |
|
|
45
|
+
| Candidate schema | JSON Schema draft 2020-12, `additionalProperties: false`; chỉ cho summary, risk và findings có evidence refs |
|
|
46
|
+
| Trust validation | Local allowlist evidence refs, loại invented URL/claim không có evidence, downgrade risk, tạo human-review policy |
|
|
47
|
+
| Evaluation Runner | Dùng cùng `analyzeDependencyAiContext`, schema và trust path với Golden Dataset |
|
|
48
|
+
| Metrics & Scorecard | Đo risk, human review, evidence, unsupported claims, validation và deterministic quality |
|
|
49
|
+
| Benchmark Runner | Wrap runtime để thu latency, token usage, estimated cost; hiện chưa thu route/fallback identity |
|
|
50
|
+
| Version Analysis Manifest | Portable trusted result; cố ý không chứa provider, model, latency, usage hay secret |
|
|
51
|
+
|
|
52
|
+
Gateway thuộc runtime boundary. Gateway không được:
|
|
53
|
+
|
|
54
|
+
- quyết định hoặc sửa `currentVersion`, `targetVersion`, dependency identity hay evidence selection;
|
|
55
|
+
- bypass Ajv, evidence allowlist, invented-URL rejection, risk downgrade hoặc human-review policy;
|
|
56
|
+
- biến model-generated facts thành deterministic facts;
|
|
57
|
+
- cho MVP-04/MVP-05 consume raw candidate trước trust validation.
|
|
58
|
+
|
|
59
|
+
### 2.2 Chuỗi rủi ro roadmap
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
Gateway đổi model/capability mà không báo
|
|
63
|
+
↓
|
|
64
|
+
MVP-03 phân loại risk hoặc evidence sai
|
|
65
|
+
↓
|
|
66
|
+
MVP-04 tìm sai vùng source code bị ảnh hưởng
|
|
67
|
+
↓
|
|
68
|
+
MVP-05 tạo migration plan sai hoặc thiếu
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Structured JSON chỉ bảo vệ shape, không bảo vệ semantic quality. Hai model cùng trả schema-valid JSON vẫn có thể khác risk classification, cách tổng hợp release notes, multilingual comprehension và mức độ tuân thủ evidence. Provider khác nhau cho cùng model slug cũng có thể khác quantization, serving config, latency, parameter support hoặc safety behavior. Vì vậy availability fallback không trung tính với analysis quality.
|
|
72
|
+
|
|
73
|
+
### 2.3 Analysis-quality requirements
|
|
74
|
+
|
|
75
|
+
Một runtime tuple chỉ được hiểu là:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
(gateway, gatewayVersion, requestedModel, actualModel,
|
|
79
|
+
requestedProvider, actualProvider, structuredOutputMode, routingPolicy)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Tuple phải chứng minh:
|
|
83
|
+
|
|
84
|
+
- instruction following và JSON Schema adherence;
|
|
85
|
+
- evidence-grounded synthesis và version/release reasoning;
|
|
86
|
+
- context window đủ cho context đã bounded;
|
|
87
|
+
- multilingual evidence nếu Golden Dataset có case tương ứng;
|
|
88
|
+
- exact requested route và actual route quan sát được;
|
|
89
|
+
- timeout, usage, latency, error taxonomy và fallback visibility;
|
|
90
|
+
- không silent downgrade từ JSON Schema sang JSON mode/prompt-only;
|
|
91
|
+
- không có request/response transform ngoài profile đã benchmark.
|
|
92
|
+
|
|
93
|
+
Pin route không tạo bitwise determinism. Model serving vẫn có thể nondeterministic hoặc được upstream cập nhật; evaluation phải dùng repeated runs và lưu identity/version metadata thay vì hứa tái tạo byte-for-byte.
|
|
94
|
+
|
|
95
|
+
## 3. 9Router Findings
|
|
96
|
+
|
|
97
|
+
### 3.1 Architecture và OSS suitability
|
|
98
|
+
|
|
99
|
+
9Router là local Next.js gateway/dashboard. Kiến trúc chính thức mô tả `/v1/*`, translation, model-combo fallback, account fallback, OAuth/API-key connections, usage/cost tracking, request logging và optional cloud sync. State gồm providers, credentials, aliases, combos, settings và pricing được persist local; usage/request details cũng được persist. [Architecture](https://github.com/decolua/9router/blob/master/docs/ARCHITECTURE.md)
|
|
100
|
+
|
|
101
|
+
Repository dùng MIT License, hỗ trợ chạy từ source/Docker và package global. Đây là bằng chứng đủ để xem 9Router là một OSS/self-hosted gateway phù hợp cho contributor tự nguyện cài, nhưng không phải lý do để thêm nó vào dependency tree của UpgradeLens. [License](https://github.com/decolua/9router/blob/master/LICENSE) · [README](https://github.com/decolua/9router/blob/master/README.md)
|
|
102
|
+
|
|
103
|
+
Dependency/operational footprint lớn hơn direct Ollama endpoint: Next.js dashboard, local database, provider registry, OAuth/token refresh, translators, executors, logging và optional sync/tunnel. Contributor còn phụ thuộc vào upstream provider, API key, OAuth/subscription hoặc local endpoint mà họ chọn. “Gateway local” không đồng nghĩa “inference offline”.
|
|
104
|
+
|
|
105
|
+
### 3.2 Request, model và account routing
|
|
106
|
+
|
|
107
|
+
Model string `provider-or-alias/model` được parse thành provider + model. Model string không có `/` có thể resolve qua alias; nếu không resolve được, 9Router infer provider theo model prefix và cuối cùng mặc định OpenAI. Vì vậy UpgradeLens không được dùng bare alias trong evaluation; phải dùng provider-prefixed model. [Model resolution source](https://github.com/decolua/9router/blob/master/open-sse/services/model.js)
|
|
108
|
+
|
|
109
|
+
Combos là virtual model names. Source và docs cho thấy ba dạng behavior liên quan:
|
|
110
|
+
|
|
111
|
+
- fallback: thử model theo thứ tự đến khi thành công;
|
|
112
|
+
- round-robin/sticky: đổi model đầu tiên theo state trong memory;
|
|
113
|
+
- fusion: fan-out sang nhiều model rồi dùng judge model tổng hợp.
|
|
114
|
+
|
|
115
|
+
Combo còn có capability-based auto-switch để reorder model. Capability detector hiện tập trung vào input modalities và không dùng `response_format`/JSON Schema làm hard capability. Do đó một fallback model có thể không tương đương structured-output quality với model đầu. [Combos documentation](https://github.com/decolua/9router/blob/master/gitbook/content/en/features/combos.md) · [Combo source](https://github.com/decolua/9router/blob/master/open-sse/services/combo.js)
|
|
116
|
+
|
|
117
|
+
Kết luận control:
|
|
118
|
+
|
|
119
|
+
- **Pin model/provider:** `SUPPORTED` khi request dùng exact `provider/model`, không alias/combo.
|
|
120
|
+
- **Disable cross-model fallback:** `PARTIAL`; có thể tránh bằng cách không dùng combo/fusion/round-robin, nhưng không thấy documented per-request `allow_fallbacks=false` tương đương OpenRouter.
|
|
121
|
+
- **Pin account:** `UNKNOWN`; source chứng minh account fallback/model locks nhưng không có public per-request contract để chọn exact connection và tắt account failover. Controlled benchmark phải chỉ enable một connection hoặc xem account change là invalid run.
|
|
122
|
+
- **Exact reproduction:** `PARTIAL`; cần khóa gateway version/config/account/model/transforms và vẫn chỉ đạt bounded, không bitwise, reproducibility.
|
|
123
|
+
|
|
124
|
+
### 3.3 Structured output
|
|
125
|
+
|
|
126
|
+
9Router nhận OpenAI `response_format` và ghi nó vào request detail. Khả năng preserve phụ thuộc đường translation:
|
|
127
|
+
|
|
128
|
+
- native OpenAI-compatible passthrough có thể giữ `response_format` nếu upstream hỗ trợ;
|
|
129
|
+
- OpenAI → Claude translator nhận `json_schema` nhưng chuyển schema thành system-prompt instruction “respond with valid JSON”, không phải native constrained decoding;
|
|
130
|
+
- docs/source không chứng minh mọi Gemini/Claude/custom provider preserve toàn bộ JSON Schema semantics;
|
|
131
|
+
- combo capability ordering không bắt buộc structured-output support;
|
|
132
|
+
- local Ajv của UpgradeLens vẫn phát hiện output sai schema, nhưng chỉ sau khi đã tốn request và không ngăn semantic drift.
|
|
133
|
+
|
|
134
|
+
Vì vậy “preserve JSON Schema qua mọi upstream provider” là **không được chứng minh** và đánh giá `PARTIAL`, không phải `SUPPORTED`. [OpenAI-to-Claude translation](https://github.com/decolua/9router/blob/master/open-sse/translator/request/openai-to-claude.js) · [Chat core](https://github.com/decolua/9router/blob/master/open-sse/handlers/chatCore.js)
|
|
135
|
+
|
|
136
|
+
Evaluation/production phải fail khi upstream không hỗ trợ schema thật; không được tự động coi prompt-only JSON là capability tương đương. Mỗi 9Router provider/model path phải qua conformance fixture và live opt-in validation riêng.
|
|
137
|
+
|
|
138
|
+
### 3.4 Token optimization và analysis integrity
|
|
139
|
+
|
|
140
|
+
9Router có RTK compression, Headroom/PXPIPE transforms, Caveman/Ponytail prompt injection và modality stripping/prefetch trong chat core. RTK sửa tool-result content; Caveman/Ponytail sửa system prompt. Dù Version Analysis hiện không dùng tool calls, policy phải tắt mọi transform cho evaluation và production-like benchmark. Nếu bật transform thì đó là một runtime tuple khác, cần benchmark riêng và trace phải ghi nhận.
|
|
141
|
+
|
|
142
|
+
Không dùng fusion cho Version Analysis: fusion bỏ tools ở panel calls, thêm judge prompt, che danh tính source model và có thể degrade sang một panel answer. Đây là một analysis pipeline khác, không còn là cùng prompt/model contract.
|
|
143
|
+
|
|
144
|
+
### 3.5 Usage, latency, cost và audit
|
|
145
|
+
|
|
146
|
+
9Router lưu provider, model, connectionId, token fields, latency, request, translated provider request, provider response và response summary trong local request detail. Điều này đủ để debug local nhưng tạo hai hạn chế:
|
|
147
|
+
|
|
148
|
+
- public OpenAI response không có documented stable field chứa actual provider/connection/fallback chain;
|
|
149
|
+
- returned usage có normalization/estimation và source còn thêm buffer token trong một số response paths, nên không nên coi là provider-billing truth.
|
|
150
|
+
|
|
151
|
+
Dashboard cost là tracking/estimate; README nói 9Router không bill và contributor trả upstream trực tiếp. Benchmark có thể dùng client wall-clock latency và normalized token usage, nhưng cost chỉ được ghi `null` hoặc “estimated” trừ khi upstream cung cấp authoritative cost. [Usage tracking source](https://github.com/decolua/9router/blob/master/open-sse/utils/usageTracking.js) · [README billing section](https://github.com/decolua/9router/blob/master/README.md#understanding-9router-costs--billing)
|
|
152
|
+
|
|
153
|
+
### 3.6 Security và privacy
|
|
154
|
+
|
|
155
|
+
Prompt/evidence được gửi tới upstream đã chọn. Với remote upstream, data rời máy dù gateway chạy localhost. 9Router persist provider secrets/connections và request details local; optional request logs có thể lưu thêm body/response; optional cloud sync/tunnel mở thêm trust boundary. Source không cung cấp một UpgradeLens-specific evidence redaction contract.
|
|
156
|
+
|
|
157
|
+
Policy tối thiểu:
|
|
158
|
+
|
|
159
|
+
- contributor phải explicit opt-in trước khi gửi private source/evidence;
|
|
160
|
+
- bind localhost và bật API-key protection nếu expose ra network;
|
|
161
|
+
- tắt cloud sync/tunnel/request debug logs cho private analysis;
|
|
162
|
+
- giới hạn quyền file database/backups và không commit chúng;
|
|
163
|
+
- không dùng OAuth/subscription/MITM integration nếu terms hoặc organizational policy chưa cho phép;
|
|
164
|
+
- không log full prompt/evidence trong UpgradeLens execution trace.
|
|
165
|
+
|
|
166
|
+
### 3.7 Suitability decision
|
|
167
|
+
|
|
168
|
+
| Use case | Đánh giá | Điều kiện |
|
|
169
|
+
| --- | --- | --- |
|
|
170
|
+
| Local contributor smoke | `SUPPORTED` | Contributor opt-in; route cụ thể; không coi smoke là quality proof |
|
|
171
|
+
| Daily multi-provider development | `SUPPORTED` | Fallback/transforms được phép và trace route khi debug |
|
|
172
|
+
| Deterministic evaluation | `PARTIAL` | Exact `provider/model`, một account, no combo, all transforms off, version/config pinned |
|
|
173
|
+
| Quality benchmark baseline | `NOT_RECOMMENDED` mặc định | Chỉ thành candidate sau LR-03 conformance; direct route làm control tốt hơn |
|
|
174
|
+
| Production-like analysis | `PARTIAL` | Allowlisted tuple đã vượt quality gate, privacy accepted, actual route recoverable |
|
|
175
|
+
| Multi-provider fallback | `SUPPORTED` cho availability | Không được dùng làm quality-equivalent fallback nếu từng tuple chưa validation |
|
|
176
|
+
|
|
177
|
+
Quyết định: 9Router nên là **OSS gateway khuyến nghị tùy chọn cho contributor và daily development**, không phải default runtime/dependency và không phải canonical benchmark route.
|
|
178
|
+
|
|
179
|
+
## 4. OpenRouter Findings
|
|
180
|
+
|
|
181
|
+
### 4.1 API, models và default routing
|
|
182
|
+
|
|
183
|
+
OpenRouter cung cấp hosted OpenAI-compatible `/api/v1/chat/completions` và Models API. Model được chọn bằng slug; Models API trả `supported_parameters`, context, pricing và provider information. Mặc định OpenRouter load-balances/fallback giữa provider endpoints để tăng uptime. [API overview](https://openrouter.ai/docs/api/reference/overview) · [Models](https://openrouter.ai/docs/guides/overview/models) · [Provider routing](https://openrouter.ai/docs/guides/routing/provider-selection)
|
|
184
|
+
|
|
185
|
+
Default routing phù hợp availability nhưng không đủ benchmark reproducibility. Locked route cho UpgradeLens phải gửi:
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"model": "<exact-model-slug>",
|
|
190
|
+
"provider": {
|
|
191
|
+
"only": ["<provider-slug>"],
|
|
192
|
+
"allow_fallbacks": false,
|
|
193
|
+
"require_parameters": true,
|
|
194
|
+
"zdr": true
|
|
195
|
+
},
|
|
196
|
+
"response_format": {
|
|
197
|
+
"type": "json_schema",
|
|
198
|
+
"json_schema": {
|
|
199
|
+
"name": "upgrade_lens_version_analysis",
|
|
200
|
+
"strict": true,
|
|
201
|
+
"schema": {}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`zdr: true` là privacy policy đề xuất, không phải capability requirement và có thể làm route không còn provider phù hợp. Nếu không có route thỏa model + provider + schema + privacy, evaluation phải fail fast.
|
|
208
|
+
|
|
209
|
+
### 4.2 Structured output và fail-fast behavior
|
|
210
|
+
|
|
211
|
+
OpenRouter document `response_format.type=json_schema` cho compatible models. Models API dùng `supported_parameters` với `structured_outputs`/`response_format`; `require_parameters: true` giới hạn route vào provider hỗ trợ toàn bộ parameters trong request. [Structured Outputs](https://openrouter.ai/docs/guides/features/structured-outputs) · [Model API](https://openrouter.ai/docs/api/api-reference/models/get-model)
|
|
212
|
+
|
|
213
|
+
Đây là capability tốt hơn 9Router cho benchmark, nhưng vẫn cần local Ajv/trust validation. “Supported” không chứng minh semantic grounding và provider implementation có thể lỗi. Policy không bật response-healing hoặc context-compression plugin trong baseline vì chúng materially alter response/request; nếu dùng, router metadata phải ghi pipeline stage và tuple phải benchmark riêng.
|
|
214
|
+
|
|
215
|
+
OpenRouter có thể fail fast thay vì route yếu hơn bằng tổ hợp:
|
|
216
|
+
|
|
217
|
+
- exact model slug, không dùng alias `latest`;
|
|
218
|
+
- `provider.only` đúng một provider;
|
|
219
|
+
- `allow_fallbacks: false`;
|
|
220
|
+
- `require_parameters: true`;
|
|
221
|
+
- không gửi `models`/`fallbacks`;
|
|
222
|
+
- reject response nếu actual identity hoặc routing metadata khác policy.
|
|
223
|
+
|
|
224
|
+
### 4.3 Reproducibility và actual identity
|
|
225
|
+
|
|
226
|
+
OpenRouter response trả actual model; generation stats trả model, `provider_name`, latency, native token counts và total cost. Tốt hơn nữa, request header `X-OpenRouter-Metadata: enabled` thêm `openrouter_metadata` vào response với requested route, strategy, selected endpoint, attempt number, attempts và pipeline transforms. [Router Metadata](https://openrouter.ai/docs/guides/features/router-metadata) · [Generation stats](https://openrouter.ai/docs/api/api-reference/generations/get-generation)
|
|
227
|
+
|
|
228
|
+
Locked route vì vậy audit được tốt, nhưng không bitwise reproducible: upstream model/provider có thể cập nhật serving stack và exact weights/revision không phải lúc nào cũng nằm trong slug. Benchmark phải lưu timestamp, model slug, provider slug, generation ID, route metadata và lặp lại samples.
|
|
229
|
+
|
|
230
|
+
### 4.4 Auto/free/fallback routes
|
|
231
|
+
|
|
232
|
+
Không dùng các route sau làm Version Analysis quality benchmark hoặc input production mặc định:
|
|
233
|
+
|
|
234
|
+
- `openrouter/auto`: router chọn model;
|
|
235
|
+
- `openrouter/free`: chọn ngẫu nhiên trong tập free models sau capability filtering;
|
|
236
|
+
- `models` hoặc `fallbacks`: có thể đổi model khi rate limit, downtime, moderation hoặc context error;
|
|
237
|
+
- provider fallback mặc định: có thể đổi serving provider cho cùng model.
|
|
238
|
+
|
|
239
|
+
OpenRouter docs xác nhận response `model` là model cuối cùng dùng và model fallback có thể kích hoạt bởi nhiều loại lỗi. Free router tự mô tả là random selection. Hai cơ chế hữu ích cho smoke/availability, nhưng `NOT_RECOMMENDED` cho quality comparison và roadmap input. [Model fallbacks](https://openrouter.ai/docs/guides/routing/model-fallbacks) · [Free router](https://openrouter.ai/openrouter/free/api)
|
|
240
|
+
|
|
241
|
+
### 4.5 Usage, latency, cost và errors
|
|
242
|
+
|
|
243
|
+
Non-streaming completion có `usage`; generation stats có native token counts, latency và `total_cost`. Không cần suy đoán bảng giá hiện tại. Cost benchmark lấy authoritative per-generation field khi có, nếu không để `null`; không tự tính từ marketing price.
|
|
244
|
+
|
|
245
|
+
OpenRouter document error types/status, `Retry-After`, pre-stream retry/fallback và giới hạn không thể fail over sau khi stream đã phát token. UpgradeLens baseline vẫn là non-streaming; client deadline và bounded retry mới là authority. [Errors and debugging](https://openrouter.ai/docs/api/reference/errors-and-debugging)
|
|
246
|
+
|
|
247
|
+
### 4.6 Privacy
|
|
248
|
+
|
|
249
|
+
Evidence đi qua OpenRouter và upstream provider. Official docs nói OpenRouter không lưu prompt/response trừ khi người dùng opt in logging/data use, nhưng vẫn lưu request metadata; upstream providers có policy riêng. `zdr: true` chỉ route tới ZDR endpoints. [Data collection](https://openrouter.ai/docs/guides/privacy/data-collection) · [Zero Data Retention](https://openrouter.ai/docs/guides/features/zdr) · [Provider logging](https://openrouter.ai/docs/guides/privacy/provider-logging)
|
|
250
|
+
|
|
251
|
+
Vì source/evidence tương lai có thể chứa private code, OpenRouter không được là OSS default. UI/CLI phải có explicit cloud opt-in và cảnh báo trước khi private material rời máy. Input/output logging và data-discount logging phải off cho UpgradeLens analysis; route cần ZDR/data policy phù hợp organization.
|
|
252
|
+
|
|
253
|
+
### 4.7 Suitability decision
|
|
254
|
+
|
|
255
|
+
| Use case | Đánh giá | Điều kiện |
|
|
256
|
+
| --- | --- | --- |
|
|
257
|
+
| Cloud smoke | `SUPPORTED` | Có account/key, contributor opt-in, không suy ra quality |
|
|
258
|
+
| Model comparison | `SUPPORTED` | Mỗi exact model/provider là một run riêng |
|
|
259
|
+
| Prompt/quality benchmark | `SUPPORTED` | Locked route, metadata enabled, no plugins/fallback/auto/free |
|
|
260
|
+
| Production-like analysis | `SUPPORTED` có điều kiện | Allowlist + quality gate + privacy + trace + fail on unknown identity |
|
|
261
|
+
| Availability fallback | `SUPPORTED` | Chỉ giữa các tuple đã validation; occurrence luôn recorded |
|
|
262
|
+
| Default OSS runtime | `NOT_RECOMMENDED` | Cloud/account/cost/privacy không phù hợp default contributor path |
|
|
263
|
+
|
|
264
|
+
Quyết định: OpenRouter nên là **cloud benchmark gateway chính**, không phải runtime mặc định của dự án OSS.
|
|
265
|
+
|
|
266
|
+
## 5. Compatibility and Suitability Matrix
|
|
267
|
+
|
|
268
|
+
Nhãn đánh giá capability trong mode an toàn cho Version Analysis, không phải feature marketing. `Direct provider` là category không đồng nhất nên các capability phụ thuộc provider/model cụ thể.
|
|
269
|
+
|
|
270
|
+
| Capability | 9Router | OpenRouter | Direct Ollama | Direct provider |
|
|
271
|
+
| --- | --- | --- | --- | --- |
|
|
272
|
+
| OSS/self-hosted | `SUPPORTED` | `NOT_SUPPORTED` | `SUPPORTED` | `PARTIAL` |
|
|
273
|
+
| OpenAI compatibility | `SUPPORTED` | `SUPPORTED` | `SUPPORTED` | `PARTIAL` |
|
|
274
|
+
| JSON Schema | `PARTIAL` — translation có thể thành prompt-only | `SUPPORTED` — compatible endpoint + required parameter | `SUPPORTED` — model quality vẫn ảnh hưởng | `PARTIAL` — provider/model-specific |
|
|
275
|
+
| Model pinning | `SUPPORTED` — exact `provider/model` | `SUPPORTED` — exact slug | `SUPPORTED` — dùng immutable tag/digest nếu có | `SUPPORTED` |
|
|
276
|
+
| Provider pinning | `SUPPORTED` — provider prefix | `SUPPORTED` — `provider.only` | `SUPPORTED` — endpoint fixed | `SUPPORTED` — endpoint fixed |
|
|
277
|
+
| Fallback control | `PARTIAL` — tránh combo; account failover per-request chưa rõ | `SUPPORTED` — `allow_fallbacks:false`, no model fallbacks | `SUPPORTED` — không router fallback | `PARTIAL` — client/provider-specific |
|
|
278
|
+
| Actual model identity | `PARTIAL` — local detail tốt, public stable contract chưa đủ | `SUPPORTED` — response + router metadata/generation | `SUPPORTED` — configured/response model | `SUPPORTED` thường có; verify per provider |
|
|
279
|
+
| Actual provider identity | `PARTIAL` — local detail, không stable response field | `SUPPORTED` — selected endpoint/provider metadata | `SUPPORTED` — local endpoint identity | `SUPPORTED` — endpoint identity |
|
|
280
|
+
| Token usage | `PARTIAL` — normalized/estimated/buffered paths | `SUPPORTED` — response + native generation counts | `SUPPORTED` | `PARTIAL` — provider-specific |
|
|
281
|
+
| Latency | `PARTIAL` — local detail/client wall clock | `SUPPORTED` — generation + client wall clock | `PARTIAL` — client/runtime fields | `PARTIAL` — provider-specific |
|
|
282
|
+
| Cost | `PARTIAL` — dashboard estimate, upstream billing external | `SUPPORTED` — generation `total_cost` | `NOT_SUPPORTED` — không per-request bill | `PARTIAL` — billing API-specific |
|
|
283
|
+
| Offline capability | `PARTIAL` — server local, upstream quyết định | `NOT_SUPPORTED` | `SUPPORTED` | `PARTIAL` — local provider only |
|
|
284
|
+
| Privacy | `PARTIAL` — local persistence nhưng remote upstream/log/sync risks | `PARTIAL` — cloud; ZDR/data controls | `SUPPORTED` nếu local-only | `PARTIAL` — policy-specific |
|
|
285
|
+
| Reproducibility | `PARTIAL` — locked profile bắt buộc | `PARTIAL` — locked route, upstream vẫn mutable | `PARTIAL` — pin model artifact/config | `PARTIAL` — pin revision/config nếu có |
|
|
286
|
+
| Evaluation suitability | `PARTIAL` | `SUPPORTED` có điều kiện | `SUPPORTED` có điều kiện | `SUPPORTED` có điều kiện |
|
|
287
|
+
| Benchmark suitability | `PARTIAL` — không baseline mặc định | `SUPPORTED` có điều kiện | `SUPPORTED` làm local control | `SUPPORTED` có điều kiện |
|
|
288
|
+
| Production-analysis suitability | `PARTIAL` | `SUPPORTED` có điều kiện | `PARTIAL` — model quality quyết định | `SUPPORTED` có điều kiện |
|
|
289
|
+
|
|
290
|
+
Các `UNKNOWN` discovery còn lại:
|
|
291
|
+
|
|
292
|
+
- **9Router exact account pinning:** thiếu documented public request field để chọn một connection và disable account fallback.
|
|
293
|
+
- **9Router universal schema preservation:** thiếu conformance evidence cho mọi translator/upstream; source đã chứng minh ít nhất Claude path là prompt instruction thay vì native constraint.
|
|
294
|
+
- **9Router stable public fallback metadata:** thiếu documented response contract chứa toàn bộ attempted/selected provider-model-account chain.
|
|
295
|
+
- **Direct provider category:** không thể kết luận chung về retention, revisions, usage/cost và retry nếu chưa chọn provider/model cụ thể.
|
|
296
|
+
|
|
297
|
+
## 6. Routing Policy
|
|
298
|
+
|
|
299
|
+
### Development mode
|
|
300
|
+
|
|
301
|
+
- Direct Ollama là đường smoke local đơn giản nhất.
|
|
302
|
+
- 9Router được phép combo/fallback để tăng availability trong daily development, nhưng output chỉ là development signal.
|
|
303
|
+
- OpenRouter auto/free/fallback chỉ được dùng cho cloud smoke, không gắn nhãn benchmark/production-quality.
|
|
304
|
+
- Luôn chạy local schema/trust validation; route failure không được đổi deterministic facts.
|
|
305
|
+
- Log route identity khi có, nhưng không log full prompt/evidence.
|
|
306
|
+
|
|
307
|
+
### Evaluation mode
|
|
308
|
+
|
|
309
|
+
- Pin exact model; pin provider khi gateway có provider router.
|
|
310
|
+
- 9Router: exact `provider/model`, no alias/combo/fusion/round-robin, một enabled account, RTK/Headroom/PXPIPE/Caveman/Ponytail và other transforms off.
|
|
311
|
+
- OpenRouter: exact non-`latest` slug, một `provider.only`, `allow_fallbacks:false`, `require_parameters:true`, no `models`/`fallbacks`, no auto/free/plugins; bật `X-OpenRouter-Metadata: enabled`.
|
|
312
|
+
- Native `json_schema` là bắt buộc. Capability rejection phải fail, không retry với JSON mode/prompt-only.
|
|
313
|
+
- Actual provider/model phải khớp requested policy. Unknown/mismatch làm run invalid.
|
|
314
|
+
- Gateway version/config digest, fallback attempts, latency, usage/cost được ghi ở execution trace ngoài portable manifest.
|
|
315
|
+
|
|
316
|
+
### Production analysis mode
|
|
317
|
+
|
|
318
|
+
- Chỉ allowlist runtime tuple đã vượt cùng Golden Dataset/scorecard gate.
|
|
319
|
+
- Structured-output capability là precondition; không silent downgrade.
|
|
320
|
+
- Fallback chỉ sang exact tuple đã validation độc lập; fallback occurrence bắt buộc ghi trace và trigger human review trước MVP-04.
|
|
321
|
+
- Fail closed nếu actual provider/model không xác định, route ngoài allowlist hoặc pipeline transform ngoài policy.
|
|
322
|
+
- Cloud runtime cần explicit user/operator opt-in, private-data warning và privacy policy phù hợp.
|
|
323
|
+
- `requiresHumanReview`/`nextAction` từ trust layer vẫn là authority; gateway không được override.
|
|
324
|
+
|
|
325
|
+
## 7. Benchmark Strategy
|
|
326
|
+
|
|
327
|
+
### 7.1 Controlled comparison
|
|
328
|
+
|
|
329
|
+
So sánh ba route:
|
|
330
|
+
|
|
331
|
+
```text
|
|
332
|
+
Direct Ollama exact model artifact
|
|
333
|
+
vs
|
|
334
|
+
9Router exact provider/model, locked profile
|
|
335
|
+
vs
|
|
336
|
+
OpenRouter exact model/provider, locked route
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Giữ nguyên cho mọi run:
|
|
340
|
+
|
|
341
|
+
- Golden Dataset version và case order;
|
|
342
|
+
- prompt version;
|
|
343
|
+
- candidate output schema/digest;
|
|
344
|
+
- local Ajv validation, trust validation, comparator, Metrics và Scorecard;
|
|
345
|
+
- timeout/retry policy;
|
|
346
|
+
- non-streaming request;
|
|
347
|
+
- versioned repeat count lớn hơn một để đo variance.
|
|
348
|
+
|
|
349
|
+
Không so một router alias với một exact model rồi gọi đó là model comparison. Mỗi actual `(model, provider)` là một candidate riêng. Sample có route mismatch, unexpected fallback, cache replay thiếu route metadata hoặc capability downgrade bị loại/invalidate, không trộn vào average.
|
|
350
|
+
|
|
351
|
+
### 7.2 Metrics
|
|
352
|
+
|
|
353
|
+
Quality metrics:
|
|
354
|
+
|
|
355
|
+
- schema-valid/validation pass rate;
|
|
356
|
+
- risk classification accuracy;
|
|
357
|
+
- human-review accuracy và reason accuracy;
|
|
358
|
+
- evidence-reference accuracy, evidence coverage accuracy/reference coverage;
|
|
359
|
+
- current trust-layer unsupported-claim proxy (`CLAIMS_DROPPED`) và raw unsupported claim rate trước trust nếu runner sau này có thể quan sát an toàn;
|
|
360
|
+
- published unsupported claim rate sau trust;
|
|
361
|
+
- deterministic pass rate và cross-repeat variance.
|
|
362
|
+
|
|
363
|
+
Runtime metrics:
|
|
364
|
+
|
|
365
|
+
- end-to-end latency và gateway/upstream latency khi có;
|
|
366
|
+
- prompt/completion/total tokens, cache/reasoning tokens khi có;
|
|
367
|
+
- authoritative cost hoặc `null`, không suy đoán;
|
|
368
|
+
- fallback/attempt count;
|
|
369
|
+
- actual model/provider changes;
|
|
370
|
+
- schema capability rejection, timeout và normalized error category;
|
|
371
|
+
- request/response transform pipeline flags.
|
|
372
|
+
|
|
373
|
+
### 7.3 Interpretation
|
|
374
|
+
|
|
375
|
+
- Direct Ollama là local control, không tự động là quality winner.
|
|
376
|
+
- 9Router pinned route phải được so với cùng upstream direct route khi có thể; chênh lệch chỉ ra translation/transform/observability effects.
|
|
377
|
+
- OpenRouter pinned route cho phép cloud model comparison; một provider khác là một run mới.
|
|
378
|
+
- Availability và quality được báo riêng. Fallback làm tăng success rate không được che regression về risk/evidence/schema.
|
|
379
|
+
- Không chạy benchmark trong LR-00A.
|
|
380
|
+
|
|
381
|
+
## 8. Artifact and Observability Requirements
|
|
382
|
+
|
|
383
|
+
`version-analysis.json` tiếp tục portable và provider-neutral. Không thêm execution telemetry vào manifest hiện tại vì nó sẽ làm artifact phụ thuộc deployment, chứa identifiers/cost và làm thay đổi downstream contract không cần thiết.
|
|
384
|
+
|
|
385
|
+
Optional execution trace ngoài portable artifact nên có shape khái niệm:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"schemaVersion": "1",
|
|
390
|
+
"runId": "...",
|
|
391
|
+
"contextId": "...",
|
|
392
|
+
"startedAt": "...",
|
|
393
|
+
"gateway": "9router|openrouter|none",
|
|
394
|
+
"gatewayVersion": "...",
|
|
395
|
+
"routingPolicyDigest": "sha256:...",
|
|
396
|
+
"requestedModel": "...",
|
|
397
|
+
"actualModel": "...",
|
|
398
|
+
"requestedProvider": "...",
|
|
399
|
+
"actualProvider": "...",
|
|
400
|
+
"structuredOutputMode": "jsonSchema",
|
|
401
|
+
"fallbackOccurred": false,
|
|
402
|
+
"attemptCount": 1,
|
|
403
|
+
"pipelineTransforms": [],
|
|
404
|
+
"latencyMs": 0,
|
|
405
|
+
"tokenUsage": {},
|
|
406
|
+
"cost": null,
|
|
407
|
+
"generationId": "...",
|
|
408
|
+
"finishReason": "...",
|
|
409
|
+
"errorCategory": null
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Benchmark cần thêm `datasetVersion`, `promptVersion`, `outputSchemaDigest`, repeat/sample index và scorecard linkage. Audit production cần run/context IDs, timestamp, gateway version, selected route, fallback/transform flags, generation/request correlation ID, privacy mode và normalized error.
|
|
414
|
+
|
|
415
|
+
Không được lưu trong portable artifact hoặc default trace:
|
|
416
|
+
|
|
417
|
+
- API key, Authorization, OAuth/subscription token, cookie hoặc raw headers;
|
|
418
|
+
- full prompt, full evidence, source code, raw request/provider request;
|
|
419
|
+
- raw response/provider error body có thể echo input;
|
|
420
|
+
- credential/connection secrets, dashboard database paths hoặc proxy URLs có credentials.
|
|
421
|
+
|
|
422
|
+
Trace writer phải redact endpoint credentials/query secrets, write file mode hạn chế và cho phép disable. Gateway-native dashboard/log không thay thế UpgradeLens trace: trace phải map vào stable local vocabulary và giữ correlation ID để operator truy vấn gateway khi được phép.
|
|
423
|
+
|
|
424
|
+
## 9. Recommended Roles
|
|
425
|
+
|
|
426
|
+
| Mode/role | Primary | Secondary | Không dùng |
|
|
427
|
+
| --- | --- | --- | --- |
|
|
428
|
+
| Local technical smoke | Direct Ollama | 9Router → local/explicit upstream | Cloud auto/free route làm local proof |
|
|
429
|
+
| OSS multi-provider development | 9Router | Direct provider | Coi fallback output là benchmark-equivalent |
|
|
430
|
+
| Cloud smoke | OpenRouter | Direct cloud provider | Gửi private evidence không opt-in |
|
|
431
|
+
| Cloud quality benchmark | OpenRouter locked route | Direct provider control | `openrouter/auto`, `openrouter/free`, model/provider fallback |
|
|
432
|
+
| Canonical local comparison | Direct Ollama pinned artifact | 9Router pinned same upstream | Combo/fusion/token transforms |
|
|
433
|
+
| Production analysis | Explicit validated runtime tuple | Validated fallback tuple | Unknown identity/capability, unvalidated fallback |
|
|
434
|
+
|
|
435
|
+
Trả lời mười decision questions:
|
|
436
|
+
|
|
437
|
+
| # | Trả lời |
|
|
438
|
+
| --- | --- |
|
|
439
|
+
| 1 | **Có điều kiện.** 9Router nên là OSS gateway tùy chọn cho contributor/daily development, không là dependency/default bắt buộc. |
|
|
440
|
+
| 2 | **Không ở default config; có điều kiện ở locked profile.** Vẫn chỉ bounded reproducibility và phải qua LR-03 conformance. |
|
|
441
|
+
| 3 | **Pin model/provider được bằng `provider/model`; disable cross-model fallback bằng cách không dùng combo.** Per-request disable account fallback/pin exact account là `UNKNOWN`. |
|
|
442
|
+
| 4 | **Không.** Không có bằng chứng universal preservation; Claude translation biến schema thành prompt instruction. |
|
|
443
|
+
| 5 | **Có điều kiện.** OpenRouter nên là cloud benchmark gateway chính khi route bị khóa và privacy được chấp nhận. |
|
|
444
|
+
| 6 | **Có.** Dùng `provider.only`, `allow_fallbacks:false`, `require_parameters:true`, exact model slug và `response_format.json_schema`. |
|
|
445
|
+
| 7 | **Không.** Auto/free router không dùng cho Version Analysis benchmark hoặc trusted roadmap input. |
|
|
446
|
+
| 8 | **Có cho transport.** Một OpenAI-compatible adapter đủ cho cả hai; không đồng nghĩa cùng capability/policy. |
|
|
447
|
+
| 9 | **Có, nhưng nhỏ và allowlisted.** OpenRouter cần `provider` body fields và `X-OpenRouter-Metadata`; 9Router baseline không cần vendor body extras. |
|
|
448
|
+
| 10 | **Chỉ exact runtime tuple đã vượt quality gate**, actual identity known, native schema enforced, trust-valid; fallback tuple phải validation độc lập. |
|
|
449
|
+
|
|
450
|
+
## 10. Architecture Decision
|
|
451
|
+
|
|
452
|
+
### Decision
|
|
453
|
+
|
|
454
|
+
Giữ `AiRuntime` và thêm một OpenAI-compatible provider theo LR-00. Gateway là optional deployment hop, không phải runtime abstraction mới.
|
|
455
|
+
|
|
456
|
+
```text
|
|
457
|
+
Deterministic Dependency AI Context
|
|
458
|
+
↓
|
|
459
|
+
AiRuntime.generateStructured
|
|
460
|
+
↓
|
|
461
|
+
OpenAiCompatibleProvider
|
|
462
|
+
├── request: model + messages + response_format
|
|
463
|
+
├── optional allowlisted headers/body extras
|
|
464
|
+
└── response: output + usage + route metadata
|
|
465
|
+
↓
|
|
466
|
+
Optional endpoint
|
|
467
|
+
├── Ollama direct
|
|
468
|
+
├── 9Router
|
|
469
|
+
├── OpenRouter
|
|
470
|
+
└── direct provider
|
|
471
|
+
↓
|
|
472
|
+
Local Ajv validation
|
|
473
|
+
↓
|
|
474
|
+
Local trust validation
|
|
475
|
+
↓
|
|
476
|
+
Portable Version Analysis Manifest
|
|
477
|
+
└── separate optional execution trace
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Gateway-specific differences được phép
|
|
481
|
+
|
|
482
|
+
- optional request body extras chỉ cho known routing keys; không được override `model`, `messages`, `response_format` hoặc `stream` do adapter sở hữu;
|
|
483
|
+
- optional headers, đặc biệt OpenRouter routing metadata opt-in, với secret redaction;
|
|
484
|
+
- gateway response metadata mapper thành stable actual provider/model/attempt/transform fields;
|
|
485
|
+
- explicit mode policy chọn/forbid extras.
|
|
486
|
+
|
|
487
|
+
Không thêm `NineRouterAdapter` hay `OpenRouterAdapter`. Nếu LR-03 chứng minh một gateway phá wire contract không thể map bằng configuration, cần ADR mới thay vì branch vendor rải trong adapter.
|
|
488
|
+
|
|
489
|
+
### MVP-04/MVP-05 quality gate
|
|
490
|
+
|
|
491
|
+
Một result chỉ được làm downstream input khi:
|
|
492
|
+
|
|
493
|
+
1. candidate qua local JSON parse + Ajv; published result qua trust validation;
|
|
494
|
+
2. `status=completed`, `validation.status` hợp lệ và `nextAction=proceedToImpactAnalysis`;
|
|
495
|
+
3. actual model/provider known, match allowlist và structured output không downgrade;
|
|
496
|
+
4. không unexpected fallback/transform; nếu fallback hợp lệ xảy ra thì `requiresHumanReview=true` trước MVP-04;
|
|
497
|
+
5. exact runtime tuple vượt scorecard thresholds hiện có:
|
|
498
|
+
- risk classification accuracy `>= 0.90`;
|
|
499
|
+
- human-review accuracy và reason accuracy `>= 0.95`;
|
|
500
|
+
- evidence-reference accuracy và reference coverage `>= 0.95`;
|
|
501
|
+
- validation pass rate `>= 0.98` trên evaluation corpus;
|
|
502
|
+
- unsupported claim rate `<= 0.05` theo metric hiện có (`CLAIMS_DROPPED` proxy); raw pre-trust rate phải báo riêng khi collector hỗ trợ;
|
|
503
|
+
- deterministic pass rate `= 1.00`;
|
|
504
|
+
6. published unsupported claims bằng `0` cho từng downstream artifact; trust layer phải drop/downgrade hoặc block phần không grounded;
|
|
505
|
+
7. gateway/model/provider/prompt/schema/dataset change làm invalid approval cũ và yêu cầu re-evaluation.
|
|
506
|
+
|
|
507
|
+
Các threshold corpus không thay thế per-result gate: một candidate sai schema hoặc unknown route không được publish chỉ vì average đạt 98%. Evaluation Runner hiện chỉ nhận trusted result, nên chưa đo trực tiếp raw pre-trust claims; không được gọi metric `CLAIMS_DROPPED` hiện tại là raw claim rate.
|
|
508
|
+
|
|
509
|
+
## 11. Implementation Impact
|
|
510
|
+
|
|
511
|
+
Tối đa ba task tiếp theo; LR-00A không triển khai task nào.
|
|
512
|
+
|
|
513
|
+
### LR-01 — OpenAI-Compatible Provider
|
|
514
|
+
|
|
515
|
+
**Scope**
|
|
516
|
+
|
|
517
|
+
- triển khai non-streaming Chat Completions mapping theo LR-00;
|
|
518
|
+
- map `outputSchema` sang strict `response_format.json_schema`;
|
|
519
|
+
- parse output/usage/model, bounded timeout/response, sanitized error taxonomy;
|
|
520
|
+
- giữ `AiRuntime` và trust contracts không đổi.
|
|
521
|
+
|
|
522
|
+
**Acceptance criteria**
|
|
523
|
+
|
|
524
|
+
- wire-compatible request/response fixtures;
|
|
525
|
+
- fail rõ với missing model, invalid envelope, refusal, schema capability error, timeout và non-2xx;
|
|
526
|
+
- secrets/prompt không xuất hiện trong error/log;
|
|
527
|
+
- generic provider chạy được với endpoint không có gateway extras.
|
|
528
|
+
|
|
529
|
+
**Tests**
|
|
530
|
+
|
|
531
|
+
- unit tests request mapping, response parsing, usage normalization, timeout/error/redaction;
|
|
532
|
+
- existing AI Version Analysis/Evaluation/Benchmark tests pass.
|
|
533
|
+
|
|
534
|
+
**Out of scope**
|
|
535
|
+
|
|
536
|
+
- cài/cấu hình gateway, live cloud calls, routing policy, new prompt/schema/trust behavior.
|
|
537
|
+
|
|
538
|
+
### LR-02 — Ollama Direct Smoke Validation
|
|
539
|
+
|
|
540
|
+
**Scope**
|
|
541
|
+
|
|
542
|
+
- opt-in local smoke dùng model contributor đã có;
|
|
543
|
+
- validate transport → candidate schema → trust path;
|
|
544
|
+
- document hardware/model caveats và no-network behavior.
|
|
545
|
+
|
|
546
|
+
**Acceptance criteria**
|
|
547
|
+
|
|
548
|
+
- một valid structured candidate đi qua local schema/trust;
|
|
549
|
+
- invalid output fail closed;
|
|
550
|
+
- không pull model tự động, không làm Ollama/model thành dependency.
|
|
551
|
+
|
|
552
|
+
**Tests**
|
|
553
|
+
|
|
554
|
+
- automated mocked conformance; manual/local test bị skip mặc định và không chạy CI cloud.
|
|
555
|
+
|
|
556
|
+
**Out of scope**
|
|
557
|
+
|
|
558
|
+
- tuyên bố production quality, tải model, benchmark 9Router/OpenRouter.
|
|
559
|
+
|
|
560
|
+
### LR-03 — Gateway Conformance, Routing Policy & Execution Trace
|
|
561
|
+
|
|
562
|
+
**Scope**
|
|
563
|
+
|
|
564
|
+
- thêm optional allowlisted request extras/headers và stable route metadata mapping;
|
|
565
|
+
- định nghĩa mode profiles cho 9Router locked và OpenRouter locked;
|
|
566
|
+
- thêm separate redacted execution trace + gateway conformance fixtures;
|
|
567
|
+
- opt-in live validation, không yêu cầu account/key trong CI.
|
|
568
|
+
|
|
569
|
+
**Acceptance criteria**
|
|
570
|
+
|
|
571
|
+
- OpenRouter profile gửi exact model, `provider.only`, fallback false, required parameters và metadata header; mismatch/unknown identity fail closed;
|
|
572
|
+
- 9Router profile cấm alias/combo/fusion/transforms và yêu cầu recoverable actual route;
|
|
573
|
+
- fallback/attempt/transform được trace; portable manifest byte contract không đổi;
|
|
574
|
+
- mode policy không cho extras override adapter-owned fields.
|
|
575
|
+
|
|
576
|
+
**Tests**
|
|
577
|
+
|
|
578
|
+
- mocked 9Router/OpenRouter wire fixtures cho pinned success, unsupported schema, fallback, identity mismatch, metadata absence và redaction;
|
|
579
|
+
- contract test chứng minh MVP-04 gate chỉ nhận trusted/approved tuple.
|
|
580
|
+
|
|
581
|
+
**Out of scope**
|
|
582
|
+
|
|
583
|
+
- gateway installation, API account creation, production deployment, benchmark execution, MVP-04/MVP-05 implementation.
|
|
584
|
+
|
|
585
|
+
## 12. Risks and Open Questions
|
|
586
|
+
|
|
587
|
+
| Risk/open question | Impact | Required resolution |
|
|
588
|
+
| --- | --- | --- |
|
|
589
|
+
| 9Router packaged version/config drift | Same model string có thể qua translator/routing khác | Trace gateway version + config digest; pin release for evaluation |
|
|
590
|
+
| 9Router account selection chưa có public per-request pin contract | Quota/account rotation khó reproduce | LR-03 source/conformance check; single enabled connection meanwhile |
|
|
591
|
+
| 9Router schema translation không native trên mọi path | Schema errors hoặc semantic drift | Provider/model allowlist; native capability conformance; fail closed |
|
|
592
|
+
| 9Router local request-detail persistence chứa prompt/provider bodies | Private evidence có thể tồn tại trên disk | Retention/redaction review trước private production use |
|
|
593
|
+
| 9Router optional cloud sync/tunnel/MITM increases trust surface | Credential/data exposure và terms risk | Off by default for UpgradeLens profile; operator approval |
|
|
594
|
+
| OpenRouter model/provider serving revisions mutable | Locked slug vẫn không bitwise reproducible | Repeated runs, timestamps, generation metadata, re-evaluate on drift |
|
|
595
|
+
| OpenRouter cache replay không có router metadata | Actual route audit có thể thiếu | Treat missing metadata as invalid evaluation sample; query generation where possible |
|
|
596
|
+
| OpenRouter upstream provider privacy differs | Evidence may be retained/trained outside expected policy | `zdr`, data policy, provider allowlist, explicit user warning/consent |
|
|
597
|
+
| Free/auto/fallback routes silently alter quality | Wrong risk/evidence can propagate downstream | Forbid in eval/production; allow only smoke/dev |
|
|
598
|
+
| Gateway cost/usage semantics differ | Misleading benchmark economics | Preserve raw normalized fields + source; authoritative cost or `null` |
|
|
599
|
+
| Native JSON Schema support does not prove grounding | Schema-valid hallucination remains possible | Keep evidence/trust gate and Golden Dataset thresholds |
|
|
600
|
+
| MVP-04/MVP-05 may consume stale approval after runtime change | Roadmap built from unvalidated model behavior | Approval key includes gateway/model/provider/prompt/schema/dataset versions |
|
|
601
|
+
|
|
602
|
+
Open questions intentionally deferred to LR-03:
|
|
603
|
+
|
|
604
|
+
- Can current 9Router release expose a stable correlation ID/API for exact selected provider, model, connection and all attempts without reading dashboard storage directly?
|
|
605
|
+
- Can account fallback be disabled or exact connection selected through a supported public request/config contract?
|
|
606
|
+
- Which 9Router translator paths preserve native JSON Schema rather than prompt-only instructions?
|
|
607
|
+
- What minimal stable execution-trace schema integrates with Benchmark Runner without changing portable Version Analysis Manifest?
|
|
608
|
+
- Which concrete model/provider tuples meet the quality gate? Discovery cannot answer this without executing the approved benchmark.
|
|
609
|
+
|
|
610
|
+
### Official evidence consulted
|
|
611
|
+
|
|
612
|
+
9Router: [website](https://9router.com/), [repository README](https://github.com/decolua/9router/blob/master/README.md), [architecture](https://github.com/decolua/9router/blob/master/docs/ARCHITECTURE.md), [license](https://github.com/decolua/9router/blob/master/LICENSE), [model resolution](https://github.com/decolua/9router/blob/master/open-sse/services/model.js), [combo routing](https://github.com/decolua/9router/blob/master/open-sse/services/combo.js), [chat core](https://github.com/decolua/9router/blob/master/open-sse/handlers/chatCore.js), [OpenAI-to-Claude translation](https://github.com/decolua/9router/blob/master/open-sse/translator/request/openai-to-claude.js), [usage tracking](https://github.com/decolua/9router/blob/master/open-sse/utils/usageTracking.js).
|
|
613
|
+
|
|
614
|
+
OpenRouter: [API overview](https://openrouter.ai/docs/api/reference/overview), [Models API](https://openrouter.ai/docs/guides/overview/models), [structured outputs](https://openrouter.ai/docs/guides/features/structured-outputs), [provider routing](https://openrouter.ai/docs/guides/routing/provider-selection), [model fallbacks](https://openrouter.ai/docs/guides/routing/model-fallbacks), [router metadata](https://openrouter.ai/docs/guides/features/router-metadata), [generation stats](https://openrouter.ai/docs/api/api-reference/generations/get-generation), [errors](https://openrouter.ai/docs/api/reference/errors-and-debugging), [data collection](https://openrouter.ai/docs/guides/privacy/data-collection), [ZDR](https://openrouter.ai/docs/guides/features/zdr), [provider logging](https://openrouter.ai/docs/guides/privacy/provider-logging).
|