@zhuoyuezs/ml-platform 0.1.17 → 0.1.19

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/checksums.json CHANGED
@@ -2,17 +2,17 @@
2
2
  "files": [
3
3
  {
4
4
  "path": "runtime/business-client/README.md",
5
- "sha256": "sha256:168e376d3eec34da4cb7966aac44b5c87239ca432d9921588f499713c6aeb24b",
6
- "size_bytes": 6122
5
+ "sha256": "sha256:61708adaee4479fe138ac5e6df1adc02be09cfeb6c30a7f9211ccc372c0e8ced",
6
+ "size_bytes": 7553
7
7
  },
8
8
  {
9
9
  "path": "runtime/business-client/package-lock.json",
10
- "sha256": "sha256:b234d20b44cbfd166efef2a9ec6d91e00488952c9a6c7ccb1fdfa50374c4b986",
10
+ "sha256": "sha256:386e8b46ae8e6d7fd83e247b0412560710bee263c2545b593c5442b8f1363765",
11
11
  "size_bytes": 381
12
12
  },
13
13
  {
14
14
  "path": "runtime/business-client/package.json",
15
- "sha256": "sha256:95551c271e726f4d69bf81b9f234b11781dc3b9a2e4b9f86db90ba8ca827ce42",
15
+ "sha256": "sha256:83e60780d91abc78420a533ba0f8ea184f31886f963ca6f1554da819530a6335",
16
16
  "size_bytes": 501
17
17
  },
18
18
  {
@@ -22,8 +22,8 @@
22
22
  },
23
23
  {
24
24
  "path": "runtime/business-client/src/cli.js",
25
- "sha256": "sha256:3739b93b0bf42bf8c0521005cfe73b080e14ec88e0fe46feb0f375575a98b7ec",
26
- "size_bytes": 53174
25
+ "sha256": "sha256:255c1ddf9521f7d6b336122a4678b1e9aab34e1ff4e894395a9e69316bacb4ad",
26
+ "size_bytes": 54119
27
27
  },
28
28
  {
29
29
  "path": "runtime/business-client/src/config.js",
@@ -37,8 +37,8 @@
37
37
  },
38
38
  {
39
39
  "path": "skills/feature-management/SKILL.md",
40
- "sha256": "sha256:e5b927611cd401bc5e6160a2d358369efd0c4f65d3fe5cbf21bbab9adb6bd978",
41
- "size_bytes": 31991
40
+ "sha256": "sha256:88898ea83ff339512d5512537db485a2764420abb67afceb9dd090cc780c00e0",
41
+ "size_bytes": 33021
42
42
  },
43
43
  {
44
44
  "path": "skills/feature-management/agents/openai.yaml",
@@ -92,13 +92,13 @@
92
92
  },
93
93
  {
94
94
  "path": "skills/feature-management/references/commands.md",
95
- "sha256": "sha256:c748f1877f6d2ac1f6ecc29e45cd270997cbd35b498a190decddb66c74b840ab",
96
- "size_bytes": 13751
95
+ "sha256": "sha256:ffd106cd785fe0d07ee20f51b7f55ca520da2fc6367bc5bc1ec0218600146d6e",
96
+ "size_bytes": 13905
97
97
  },
98
98
  {
99
99
  "path": "skills/feature-management/references/contracts.md",
100
- "sha256": "sha256:4e10ba13399de17561a10b1dead4e2fcc57e0962cf81eba5131d12d66c4ce013",
101
- "size_bytes": 29965
100
+ "sha256": "sha256:ef582d4ee9ade16de2a5f97b8bf9546969b6f2859eb020986bf25952993df402",
101
+ "size_bytes": 30483
102
102
  },
103
103
  {
104
104
  "path": "skills/feature-management/references/operator-authoring.md",
@@ -117,8 +117,8 @@
117
117
  },
118
118
  {
119
119
  "path": "skills/model-deployment-management/SKILL.md",
120
- "sha256": "sha256:5dfeab163f2c11bd4554da23e898d388a7883a2501e6a9655ee45fcada7659bb",
121
- "size_bytes": 2608
120
+ "sha256": "sha256:d50f64fa709c8ff36da97c60ce0d20b1217d1d9f78f602048f49c0c4bbab7ea2",
121
+ "size_bytes": 3927
122
122
  },
123
123
  {
124
124
  "path": "skills/model-deployment-management/agents/openai.yaml",
@@ -127,23 +127,23 @@
127
127
  },
128
128
  {
129
129
  "path": "skills/model-deployment-management/references/contracts.md",
130
- "sha256": "sha256:3b040a97dcbf3b22b194bef2bb8c1af744d434ee88a6f47deed9ee4b83cf3147",
131
- "size_bytes": 1926
130
+ "sha256": "sha256:de9fd3de8d88179b09108ee0778fb83fbffa304353706a3bbc14ae3d9276ac01",
131
+ "size_bytes": 5417
132
132
  },
133
133
  {
134
134
  "path": "skills/model-deployment-management/references/operations.md",
135
- "sha256": "sha256:410111f01b972832bd48290d280f5364cacf2e63e7d586d3b670fad9b997f695",
136
- "size_bytes": 2333
135
+ "sha256": "sha256:93977ec65a8b1ac51a5134ab98ac095e177de537c81f0db447ad97fb8a7e910f",
136
+ "size_bytes": 4455
137
137
  },
138
138
  {
139
139
  "path": "skills/model-deployment-management/references/troubleshooting.md",
140
- "sha256": "sha256:2354dfad1493c361f534a7d02dbd8ccafa4662a6ebc8e6d1b0bf8dce447dd527",
141
- "size_bytes": 1410
140
+ "sha256": "sha256:08762d603b938375cd3a76539c1d0320337d48f5bcd5ba061b8f16eaf35f9268",
141
+ "size_bytes": 3555
142
142
  },
143
143
  {
144
144
  "path": "skills/model-lifecycle-management/SKILL.md",
145
- "sha256": "sha256:74ca6bad54ddb1dc30d3307335d045a70d2d383279011657cc49c1e549eda5a6",
146
- "size_bytes": 3801
145
+ "sha256": "sha256:61a89145ef33a2d58c58d8f352006590a47cf9587705568dec1c8ffe7ed8938e",
146
+ "size_bytes": 4014
147
147
  },
148
148
  {
149
149
  "path": "skills/model-lifecycle-management/agents/openai.yaml",
@@ -162,18 +162,18 @@
162
162
  },
163
163
  {
164
164
  "path": "skills/model-lifecycle-management/references/packaging.md",
165
- "sha256": "sha256:f46a5f9c326049a0c2411fdb9d392bea2f4d667062289ee0322a5d9d328c8363",
166
- "size_bytes": 4888
165
+ "sha256": "sha256:1e3c5080fa085255b29223890c333333ee6011326b56f1b2e0b859b0d73d2ec0",
166
+ "size_bytes": 6146
167
167
  },
168
168
  {
169
169
  "path": "skills/model-lifecycle-management/references/training-contracts.md",
170
- "sha256": "sha256:b6d72f37adf40c7d3832dbe46645cd416485411dcd48ea7b93f6072d458922c9",
171
- "size_bytes": 11825
170
+ "sha256": "sha256:28fe32b2673db8f6cb1e02053bf5709826786e48dbe9951eac7bb4d98368d0c4",
171
+ "size_bytes": 12644
172
172
  },
173
173
  {
174
174
  "path": "skills/model-lifecycle-management/references/training.md",
175
- "sha256": "sha256:f7bb40919da78b99cad13d4f1f05fef136552409df5ba6e2838e1e6b4a2435a5",
176
- "size_bytes": 5508
175
+ "sha256": "sha256:97c20f02b1179dc7b7527cb7b5e11978778ccb8b76cdf88c229bcfdb5786f045",
176
+ "size_bytes": 5629
177
177
  }
178
178
  ],
179
179
  "schema_version": "data_platform.ml_platform_checksums/v1"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhuoyuezs/ml-platform",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "ML 数据平台 business CLI 与 Agent Skills 管理工具",
5
5
  "bin": {
6
6
  "ml-platform": "scripts/main.js"
package/release.json CHANGED
@@ -13,8 +13,8 @@
13
13
  "entrypoint": "src/cli.js",
14
14
  "name": "ml-platform",
15
15
  "path": "runtime/business-client",
16
- "sha256": "sha256:864a3c32efc728bda13b4e2364174e63b9054368be9062ce4f67fe1aac034720",
17
- "version": "0.7.7"
16
+ "sha256": "sha256:94d80ebfe36808fa5c0ed5585a002d8c77cb95c16b5f1ec856e5725d0d4b347f",
17
+ "version": "0.7.8"
18
18
  },
19
19
  "policy_sha256": "sha256:02fbde0134696b78c0c365d6e0b76c9814227208da5b2b3d4e5dbd82dc4a3606",
20
20
  "public_schema_versions": [
@@ -25,7 +25,7 @@
25
25
  "ml_data_platform.feature_set/v1",
26
26
  "ml_data_platform.dataset_manifest/v1"
27
27
  ],
28
- "release_version": "0.1.17",
28
+ "release_version": "0.1.19",
29
29
  "runtime_requirements": {
30
30
  "node": ">=18",
31
31
  "os": [
@@ -37,22 +37,22 @@
37
37
  "skills": {
38
38
  "feature-management": {
39
39
  "path": "skills/feature-management",
40
- "requires_cli": ">=0.7.7 <0.8.0",
41
- "revision": "0.1.17",
42
- "sha256": "sha256:182b6f2df4fe58c946e482dfaf416c7d5b78c6fde9c8c8d7293103246618cb4e"
40
+ "requires_cli": ">=0.7.8 <0.8.0",
41
+ "revision": "0.1.19",
42
+ "sha256": "sha256:d32f0306f129d7bf76eb037fe239c84dd3c29c64b61600799d6e40320784bb10"
43
43
  },
44
44
  "model-deployment-management": {
45
45
  "path": "skills/model-deployment-management",
46
- "requires_cli": ">=0.7.7 <0.8.0",
47
- "revision": "0.1.17",
48
- "sha256": "sha256:8a4c71ec8bde6c8b37c038f327797286ffa5a3ec10501278bd3d0abbab1b7509"
46
+ "requires_cli": ">=0.7.8 <0.8.0",
47
+ "revision": "0.1.19",
48
+ "sha256": "sha256:d81becca0076d0513e7b8277e7584d9f810db755aa56e79235df68d0f7a7659b"
49
49
  },
50
50
  "model-lifecycle-management": {
51
51
  "path": "skills/model-lifecycle-management",
52
- "requires_cli": ">=0.7.7 <0.8.0",
53
- "revision": "0.1.17",
54
- "sha256": "sha256:a00a50de7b7a5244a08d9865db10c812a1c6291c94ca01a8562f1b2d1ff72f2b"
52
+ "requires_cli": ">=0.7.8 <0.8.0",
53
+ "revision": "0.1.19",
54
+ "sha256": "sha256:5a911eff6a4c188d8e3709f37e4f37819effea61db9f5a015e6ec4dddd4a0ec7"
55
55
  }
56
56
  },
57
- "source_commit": "2f547af208a94ebaf2a4c61ff6ca93f11bdbf43e"
57
+ "source_commit": "ff73d381b4b895ea46ca764d9ad1bf32920faee1"
58
58
  }
@@ -22,8 +22,15 @@ ml-platform get-dataset <dataset_id> <dataset_version> --project <project>
22
22
  ml-platform resolve-dataset <dataset_id> <dataset_version> --project <project>
23
23
  ml-platform build-registered-dataset <dataset_id> <dataset_version> \
24
24
  --project <project> --wait
25
+ ml-platform register-model-artifact <artifact_id> --evaluation-id <evaluation_result_or_summary_id>
25
26
  ```
26
27
 
28
+ `resolve-dataset` 返回两个不同的身份:`manifest_hash` 是解析后的 DatasetArtifact
29
+ 缓存/构建键,`registered_manifest_hash` 是注册 DatasetManifest 的 canonical 契约哈希。
30
+ 构造 `FeatureRetrievalSpec.manifest.manifest_hash` 时必须使用后者;客户端不需要、也不应
31
+ 自行复算 Python canonical hash。模型评估结果通过 `register-model-artifact` 交给服务端治理
32
+ 校验后注册,不要绕过 CLI 直接调用 HTTP 注册接口。
33
+
27
34
  `resolve-manifest` 和 `build-dataset <manifest.json>` 仍用于尚未注册的本地契约。Catalog
28
35
  normalizer 保留并校验非默认 `project`;`apply --project` 与 Catalog 内项目不一致时拒绝执行。
29
36
 
@@ -69,9 +76,19 @@ ml-platform get-deployment-events <deployment-id> --limit 100 --offset 0
69
76
  ml-platform predict-deployment <deployment-id> /absolute/path/to/request.json
70
77
  ```
71
78
 
79
+ 部署文件可用 `inference_policy` 配置默认执行 horizon 和输出窗口。`boundary` 默认
80
+ `[start,end)`,也可显式使用 `(start,end]`。例如 15 分钟频率、
81
+ 当天 00:00 cutoff、只返回次日全天时,配置 `horizon=2d` 和 `[1d,2d)`;模型必须具备
82
+ 192 点输出能力,响应返回 96 点。请求可省略 `horizon` 和 `output_window` 使用部署默认值,
83
+ 也可携带其中任意一项覆盖;覆盖值仍受模型长度、频率和窗口边界校验。8 天、768 点模型要
84
+ 返回次日 00:15 至第八天 24:00,可配置
85
+ `{"start_offset":"1d","end_offset":"8d","boundary":"(start,end]"}`,仍返回 672 点。
86
+
72
87
  直接访问已知外部 Serving URL 时仍可使用 `predict-model`。Chronos-2 v2 的
73
88
  `known_future` 协变量放在 inline 请求的 `inputs.future_covariates` 中;每个预测步一行,
74
- 行数必须等于模型的 `prediction_length`。下例为 15 分钟频率、预测 30 分钟;预测明天时
89
+ 行数必须等于模型的 `prediction_length`。`feature_lookup` 模式不得传该字段;Serving 会从
90
+ 部署绑定的 FeatureSet 在线读取完整未来 Feature 窗口,并只使用
91
+ `available_at <= cutoff_time` 的修订。下例为 15 分钟频率、预测 30 分钟;预测明天时
75
92
  同样提供整天的所有未来步:
76
93
 
77
94
  ```json
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@zhuoyuezs/ml-platform-business-client",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@zhuoyuezs/ml-platform-business-client",
9
- "version": "0.7.7",
9
+ "version": "0.7.8",
10
10
  "license": "UNLICENSED",
11
11
  "bin": {
12
12
  "ml-platform": "src/cli.js"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhuoyuezs/ml-platform-business-client",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
4
4
  "private": true,
5
5
  "description": "JavaScript implementation of the ML Platform business client",
6
6
  "bin": {
@@ -29,12 +29,12 @@ const BUSINESS_COMMANDS = new Set([
29
29
  "add-dataset", "update-dataset", "delete-dataset", "list-dataset-artifacts",
30
30
  "register-operator", "show-operator-specs", "delete-operator", "run-operator",
31
31
  "get-job", "wait-job", "retry-job", "cancel-job", "get-dataset-artifact", "download-dataset-artifact", "fetch-inference-data", "fetch-inference-context", "predict-model", "apply",
32
- "register-trainer", "list-trainer-definitions", "get-trainer-definition", "register-training-run", "validate-training-run", "submit-training-job", "get-training-job", "retry-training-job", "cancel-training-job",
32
+ "list-system-models", "get-system-model", "list-trainer-definitions", "get-trainer-definition", "register-training-run", "validate-training-run", "submit-training-job", "get-training-job", "retry-training-job", "cancel-training-job",
33
33
  "register-evaluation-config", "get-evaluation-config", "register-metric-definition", "get-metric-definition",
34
34
  "register-executable-package", "verify-executable-package", "publish-executable-package",
35
35
  "validate-evaluation-run", "submit-evaluation", "get-evaluation-run", "get-evaluation-job", "retry-evaluation-job", "cancel-evaluation-job", "list-evaluation-attempts",
36
36
  "get-evaluation-result", "get-evaluation-result-metrics", "get-evaluation-result-artifacts", "summarize-evaluation-run", "get-evaluation-summary",
37
- "create-model-package", "get-model-package", "cancel-model-package", "validate-model-artifact",
37
+ "create-model-package", "get-model-package", "cancel-model-package", "validate-model-artifact", "register-model-artifact",
38
38
  "list-deployment-targets", "validate-deployment", "create-deployment", "list-deployments",
39
39
  "get-deployment", "wait-deployment", "reconcile-deployment", "approve-deployment",
40
40
  "promote-deployment", "rollback-deployment", "suspend-deployment", "resume-deployment",
@@ -110,7 +110,8 @@ const COMMAND_USAGE = {
110
110
  "fetch-inference-data": "fetch-inference-data MANIFEST --cutoff-time TIMESTAMP [--max-workers N] [--max-source-lag-hours HOURS] [--no-validate-freshness] [--allow-missing]",
111
111
  "fetch-inference-context": "fetch-inference-context REQUEST_JSON",
112
112
  "predict-model": "predict-model REQUEST_JSON --serving-url URL",
113
- "register-trainer": "register-trainer DEFINITION_JSON",
113
+ "list-system-models": "list-system-models",
114
+ "get-system-model": "get-system-model NAME VERSION [--project PROJECT]",
114
115
  "list-trainer-definitions": "list-trainer-definitions",
115
116
  "get-trainer-definition": "get-trainer-definition NAME VERSION [--project PROJECT]",
116
117
  "register-training-run": "register-training-run RUN_JSON",
@@ -142,6 +143,7 @@ const COMMAND_USAGE = {
142
143
  "get-model-package": "get-model-package PACKAGE_ID [--package-version VERSION]",
143
144
  "cancel-model-package": "cancel-model-package PACKAGE_ID [--package-version VERSION]",
144
145
  "validate-model-artifact": "validate-model-artifact ARTIFACT_ID",
146
+ "register-model-artifact": "register-model-artifact ARTIFACT_ID --evaluation-id EVALUATION_ID",
145
147
  "list-deployment-targets": "list-deployment-targets",
146
148
  "validate-deployment": "validate-deployment SPEC_JSON --evaluation-id ID",
147
149
  "create-deployment": "create-deployment SPEC_JSON --evaluation-id ID",
@@ -431,9 +433,8 @@ async function runBusinessCli(argv) {
431
433
  const out = take(rest, "--out");
432
434
  if (out) { const target = resolvedPath(out); fs.mkdirSync(path.dirname(target), { recursive: true }); fs.writeFileSync(target, `${JSON.stringify(result, null, 2)}\n`); }
433
435
  } else if (options.command === "resolve-dataset") {
434
- const datasetId = positional(rest, "dataset id"); const datasetVersion = positional(rest, "dataset version"); const project = take(rest, "--project", "default"); const api = client(options);
435
- const manifest = normalizeRegistryDataset(await registeredDataset(api, project, datasetId, datasetVersion));
436
- result = await api.post("/datasets/resolve", manifest);
436
+ const datasetId = positional(rest, "dataset id"); const datasetVersion = positional(rest, "dataset version"); const project = take(rest, "--project", "default");
437
+ result = await client(options).post(`/datasets/${encodeURIComponent(project)}/${encodeURIComponent(datasetId)}/${encodeURIComponent(datasetVersion)}/resolve`);
437
438
  const out = take(rest, "--out");
438
439
  if (out) { const target = resolvedPath(out); fs.mkdirSync(path.dirname(target), { recursive: true }); fs.writeFileSync(target, `${JSON.stringify(result, null, 2)}\n`); }
439
440
  } else if (options.command === "build-dataset") {
@@ -598,18 +599,23 @@ async function runBusinessCli(argv) {
598
599
  } else if (options.command === "get-executable-package") {
599
600
  const name = positional(rest, "package name"); const version = positional(rest, "package version");
600
601
  result = await client(options).get(`/executable-packages/${encodeURIComponent(name)}/${encodeURIComponent(version)}`);
602
+ } else if (options.command === "list-system-models") {
603
+ result = await client(options).get("/system-models");
604
+ } else if (options.command === "get-system-model") {
605
+ const name = positional(rest, "system model name"); const version = positional(rest, "system model version"); const project = take(rest, "--project", "default");
606
+ result = await client(options).get(`/system-models/${encodeURIComponent(project)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}`);
601
607
  } else if (options.command === "list-trainer-definitions") {
602
608
  result = await client(options).get("/trainer-definitions");
603
609
  } else if (options.command === "get-trainer-definition") {
604
610
  const name = positional(rest, "trainer name"); const version = positional(rest, "trainer version"); const project = take(rest, "--project", "default");
605
611
  result = await client(options).get(`/trainer-definitions/${encodeURIComponent(project)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}`);
606
612
  } else if ({
607
- "register-trainer": "/trainer-definitions", "register-training-run": "/training-runs", "validate-training-run": "/training-runs/validate",
613
+ "register-training-run": "/training-runs", "validate-training-run": "/training-runs/validate",
608
614
  "validate-training-job": "/training-jobs/validate", "validate-model-package": "/model-packages/validate", "submit-training-job": "/training-jobs", "register-evaluation-config": "/evaluation-configs", "register-metric-definition": "/metric-definitions",
609
615
  "register-executable-package": "/executable-packages", "validate-evaluation-run": "/evaluation-runs/validate", "submit-evaluation": "/evaluation-runs",
610
616
  "create-model-package": "/model-packages",
611
617
  }[options.command]) {
612
- const endpoint = { "register-trainer": "/trainer-definitions", "register-training-run": "/training-runs", "validate-training-run": "/training-runs/validate", "validate-training-job": "/training-jobs/validate", "validate-model-package": "/model-packages/validate", "submit-training-job": "/training-jobs", "register-evaluation-config": "/evaluation-configs", "register-metric-definition": "/metric-definitions", "register-executable-package": "/executable-packages", "validate-evaluation-run": "/evaluation-runs/validate", "submit-evaluation": "/evaluation-runs", "create-model-package": "/model-packages" }[options.command];
618
+ const endpoint = { "register-training-run": "/training-runs", "validate-training-run": "/training-runs/validate", "validate-training-job": "/training-jobs/validate", "validate-model-package": "/model-packages/validate", "submit-training-job": "/training-jobs", "register-evaluation-config": "/evaluation-configs", "register-metric-definition": "/metric-definitions", "register-executable-package": "/executable-packages", "validate-evaluation-run": "/evaluation-runs/validate", "submit-evaluation": "/evaluation-runs", "create-model-package": "/model-packages" }[options.command];
613
619
  result = await client(options).post(endpoint, readSpec(positional(rest, "request JSON")));
614
620
  } else if (/^(get|retry|cancel)-training-job$/.test(options.command)) {
615
621
  const jobId = positional(rest, "training job id"); const endpoint = `/training-jobs/${encodeURIComponent(jobId)}`;
@@ -632,6 +638,11 @@ async function runBusinessCli(argv) {
632
638
  const name = positional(rest, "package name"); const version = positional(rest, "package version"); const action = options.command.split("-")[0];
633
639
  result = await client(options).post(`/executable-packages/${encodeURIComponent(name)}/${encodeURIComponent(version)}/${action}`);
634
640
  } else if (options.command === "validate-model-artifact") result = await client(options).get(`/model-artifacts/${encodeURIComponent(positional(rest, "model artifact id"))}/validate`);
641
+ else if (options.command === "register-model-artifact") {
642
+ const artifactId = positional(rest, "model artifact id"); const evaluationId = take(rest, "--evaluation-id");
643
+ if (!evaluationId) throw new Error("--evaluation-id is required");
644
+ result = await client(options).post(`/models/${encodeURIComponent(artifactId)}/register`, { evaluation_id: evaluationId });
645
+ }
635
646
  else if (/^(get|cancel)-model-package$/.test(options.command)) {
636
647
  const packageId = positional(rest, "model package id"); const params = { package_version: take(rest, "--package-version") }; const endpoint = `/model-packages/${encodeURIComponent(packageId)}`;
637
648
  result = options.command === "get-model-package" ? await client(options).get(endpoint, params) : await client(options).post(`${endpoint}/cancel`, undefined, params);
@@ -205,11 +205,14 @@ platform source checkout or a local Catalog directory for a matching JSON file.
205
205
  target from a similar local filename.
206
206
  4. Run `get-dataset <dataset_id> <dataset_version> --project <project>` and
207
207
  inspect the returned registered contract.
208
- 5. Run `resolve-dataset` for a read-only dependency and manifest-hash check.
208
+ 5. Run `resolve-dataset` for a read-only dependency and identity check. Use its
209
+ `registered_manifest_hash` for `FeatureRetrievalSpec.manifest.manifest_hash`;
210
+ use its `manifest_hash` only as the resolved DatasetArtifact/build key.
209
211
  6. Submit exactly one `build-registered-dataset ... --wait` only after the user
210
212
  authorizes that exact registered version.
211
- 7. Use the returned Job ID with `get-job`, then use the returned manifest hash
212
- with `get-dataset-artifact` after success.
213
+ 7. Use the returned Job ID with `get-job`, then use the resolved `manifest_hash`
214
+ with `get-dataset-artifact` after success. Keep the separate
215
+ `registered_manifest_hash` for FeatureRetrievalSpec binding.
213
216
 
214
217
  Local `resolve-manifest` and `build-dataset <file>` remain authoring tools for a
215
218
  new or changed Catalog contract before it is registered. They are not required
@@ -419,6 +422,17 @@ replayable `as_of` manifest; when an online source override is active, `replay.s
419
422
  must be false because the offline manifest cannot reproduce that source. Report
420
423
  tolerated missing or gap-filled inputs as degraded freshness, not as a normal read.
421
424
 
425
+ Model-serving `feature_lookup` may additionally request declared known-future
426
+ Features from the same FeatureSet. Do not emulate that by passing model inputs
427
+ through this Skill. Author their Parameters with trustworthy availability
428
+ evidence: future event times are valid, but only revisions with
429
+ `available_at <= cutoff_time` may be used. `available_at` may therefore be
430
+ earlier than `event_time` for forecasts and schedules. The platform reads only
431
+ the requested known-future Features and their Parameter dependency closure;
432
+ unrelated historical Parameters in the same DatasetManifest do not need a
433
+ future-visibility contract. Every Parameter inside the requested closure still
434
+ fails closed when trustworthy availability is absent.
435
+
422
436
  ## Verify The Artifact
423
437
 
424
438
  Treat Registry metadata inspection and downloaded-file inspection as separate
@@ -461,7 +475,7 @@ Require all of the following before reporting success:
461
475
  windows tiling the fetch range, and any retries are accounted for;
462
476
  - missing values and warnings are reported, not silently repaired.
463
477
 
464
- The manifest hash returned by `resolve-manifest` or `resolve-dataset` is the artifact key: it stays
478
+ The `manifest_hash` returned by `resolve-manifest` or `resolve-dataset` is the artifact key: it stays
465
479
  the same after the build, so it is usable for cache reuse and polling before
466
480
  submission. Distinguish the two lookup failures rather than treating both as "not
467
481
  ready" — `422` with `invalid_artifact_key` means the key can never name an
@@ -480,7 +494,7 @@ new / unchanged assets by type
480
494
  planned versus resolved dependency versions and any explicitly retained old versions
481
495
  Operator package filename and SHA-256
482
496
  FeatureSet and ordered feature count
483
- dataset id, version, manifest hash, and Job id
497
+ dataset id, version, resolved manifest hash, registered manifest hash when applicable, and Job id
484
498
  row and column counts
485
499
  rowset candidate / policy-applied / eligible / ineligible counts when endpoint_policy is declared
486
500
  validation status, warnings, and missing-data summary
@@ -220,7 +220,8 @@ DatasetManifest hash. The initial implementation is sequential, so keep
220
220
  `--max-parallelism 1`. Completed partitions are checkpointed and resumed by
221
221
  default; use `--no-resume` only to force a clean execution.
222
222
 
223
- Record the returned `job_id`, `dataset_id`, and `manifest_hash`. If a separate wait is needed:
223
+ Record the returned `job_id`, `dataset_id`, and resolved `manifest_hash`; for a registered Dataset
224
+ also retain `registered_manifest_hash` for FeatureRetrievalSpec binding. If a separate wait is needed:
224
225
 
225
226
  ```bash
226
227
  ml-platform --profile server wait-job <job_id>
@@ -266,7 +267,8 @@ ml-platform --profile server fetch-inference-context /tmp/inference-context.json
266
267
  ```
267
268
 
268
269
  The `FeatureRetrievalSpec` must bind an existing inference-mode DatasetManifest
269
- by project, dataset id, version, and manifest hash; its FeatureSet and contract
270
+ by project, dataset id, version, and the `registered_manifest_hash` returned by
271
+ `resolve-dataset`; its FeatureSet and contract
270
272
  signature must match the resolved online contract. Context mode also fixes
271
273
  `context_length`, `frequency`, `context_end`, `stride`, input-adapter hash, and
272
274
  temporal-binding hash. Do not replace these immutable deployment bindings with
@@ -138,6 +138,12 @@ supported field.
138
138
  当前严格 `as_of` 只接受 `exact` 或有合同支撑的 `upper_bound`;修改这些语义需要发布
139
139
  新的 Parameter 业务版本。
140
140
 
141
+ 未来预报、排程、日历等 known-future 数据允许 `available_at < event_time`。这不是时钟错误:
142
+ `event_time` 是未来目标时刻,`available_at` 是该修订何时已可读取。模型
143
+ `feature_lookup` 会读取 cutoff 后的未来事件窗口,但仍严格过滤
144
+ `available_at <= cutoff_time`。因此这类 Parameter 应优先使用能表达预报签发时间或计划发布
145
+ 时间的 `source_field`,不能用事后实测值替代,也不能用调用方请求绕过 availability 合同。
146
+
141
147
  An optional `rounding` section states the fixed-point precision the platform
142
148
  enforces at the Parameter boundary:
143
149
 
@@ -28,6 +28,13 @@ deployment does not reach `READY` or an operation is rejected.
28
28
  `ml-platform --profile server health` before control-plane work.
29
29
  - Use only a `READY` ModelPackage image with an immutable `@sha256:` digest and
30
30
  the package-bound FeatureRetrievalSpec and smoke request.
31
+ - When `DeploymentSpec.inference_policy` is configured, treat its horizon and
32
+ output window as request defaults. The window boundary defaults to
33
+ `[start,end)` and may explicitly use `(start,end]`. Prediction requests may omit or
34
+ override `horizon` and `output_window`; every effective combination must fit
35
+ the model capacity and sampling grid. In `feature_lookup` mode, never send
36
+ `future_covariates`; the platform retrieves the complete known-future Feature
37
+ window visible at the cutoff. Inline mode still supplies those rows in inputs.
31
38
  - Run `validate-deployment` before `create-deployment`. Validation is read-only
32
39
  and does not authorize creation.
33
40
  - Obtain explicit authorization for the exact deployment and operation before
@@ -36,9 +43,20 @@ deployment does not reach `READY` or an operation is rejected.
36
43
  returned an ambiguous result.
37
44
  - Treat `READY` as valid only when `ReplicasReady`, `ArtifactsVerified`, and
38
45
  `SmokePredictionPassed` are all true for the current revision.
39
- - Use `predict-deployment`; it routes through the control plane to the recorded
40
- deployment endpoint. Do not infer Kubernetes Service names or require the
41
- user to reach a cluster-local URL.
46
+ - Use `predict-deployment` for governed deployment verification. Do not infer
47
+ Kubernetes Service names from a deployment ID.
48
+ - Treat every prediction response `target_time` as China Standard Time in RFC
49
+ 3339 `+08:00` form. The represented instant remains identical to the UTC
50
+ cutoff and output-window calculations.
51
+ - `DeploymentSpec.service_exposure` defaults to `ClusterIP`. An explicit
52
+ `NodePort` value creates one deployment-level direct Serving Service that
53
+ follows the current revision; it does not replace validation, approval,
54
+ rollout, READY gates, or audit history.
55
+ - Every model Serving process publishes that model's Swagger UI at `/docs`,
56
+ OpenAPI JSON at `/openapi.json`, and ReDoc at `/redoc`. The document embeds
57
+ the deployed artifact identity and its actual input modes, ordered columns,
58
+ horizon semantics, known-future contract, and output schema. These are model
59
+ data-plane documents, not the control-plane API documentation.
42
60
  - Never create, modify, or delete NetworkPolicy. Cluster operators own that
43
61
  boundary.
44
62
 
@@ -16,7 +16,23 @@ load-bearing fields:
16
16
  "package_version": "1",
17
17
  "image": "registry.example/model-serving@sha256:<64-hex>",
18
18
  "target": {"type": "kubernetes", "namespace": "itsmp-model-serving"},
19
+ "service_exposure": {
20
+ "type": "NodePort",
21
+ "port": 80,
22
+ "node_port": 32080,
23
+ "advertised_host": "10.36.9.212",
24
+ "scheme": "http"
25
+ },
19
26
  "feature_retrieval": {},
27
+ "inference_policy": {
28
+ "horizon": {"duration": "2d"},
29
+ "output_window": {
30
+ "start_offset": "1d",
31
+ "end_offset": "2d",
32
+ "boundary": "[start,end)"
33
+ },
34
+ "allow_request_override": true
35
+ },
20
36
  "replicas": 1,
21
37
  "resources": {},
22
38
  "rollout": {"strategy": "canary", "traffic_percent": 10},
@@ -29,15 +45,56 @@ They must match the registered artifact lineage and the tested ModelPackage.
29
45
  The server normalizes an omitted lookup test from the package during
30
46
  validation and creation.
31
47
 
48
+ `inference_policy` is optional. When present, its horizon and offsets must be
49
+ whole-minute durations aligned to the model sampling frequency. `boundary`
50
+ defaults to `[start,end)` and may be `(start,end]`. The selected interval must
51
+ be non-empty, end within the configured horizon, and fit the model's maximum
52
+ sequence output. A 15-minute model using `horizon=2d` and `[1d,2d)` therefore
53
+ needs at least 192 output steps and returns 96 steps. An 8-day, 768-step model
54
+ using `(1d,8d]` returns step 97 through step 768: next-day 00:15 through day-eight
55
+ 24:00, 672 points total. This is a response projection, not extra model capacity.
56
+
57
+ The deployment values are defaults. Calls may omit `horizon` and
58
+ `output_window`, override either one, or override both. Serving validates the
59
+ effective values again; an output window must remain non-empty, aligned, inside
60
+ the effective horizon, and within model capacity. Set
61
+ `allow_request_override=false` only when the endpoint must reject non-equivalent
62
+ request values. An override that omits `boundary` uses `[start,end)`; include
63
+ `boundary` explicitly to preserve `(start,end]` semantics.
64
+
65
+ Known-future covariates still cover the model's complete prediction length,
66
+ including points outside a shorter returned window. In `feature_lookup` mode,
67
+ Serving requests those Feature columns from the deployment-bound FeatureSet;
68
+ the platform permits future event times only when `available_at <= cutoff_time`.
69
+ The prediction caller must not send top-level `future_covariates`. Inline mode
70
+ continues to carry them in `inputs.future_covariates`.
71
+
32
72
  The first deployment starts at `staging`. A replacement for an existing
33
73
  service/environment declares the active leaf in `previous_deployment_id`.
34
74
  Production is reached only by staging to canary to production promotion.
35
75
 
76
+ `service_exposure` is optional and defaults to `{"type":"ClusterIP"}`. Set
77
+ `type=NodePort` only when direct node access is required. `node_port` is
78
+ optional; when omitted Kubernetes allocates it, and the observed endpoint
79
+ reports the assigned value. An explicit value must be in `30000..32767`.
80
+ `advertised_host` is also optional: provide it only when that node address is
81
+ known to be reachable by callers. Without it, the endpoint returns a URL
82
+ template rather than claiming external reachability.
83
+
84
+ The controller keeps preview, stable, and canary Services as ClusterIP for
85
+ verification and Gateway traffic. NodePort exposure uses one fixed-name Service
86
+ per DeploymentSpec and creates or updates it only after the revision passes all
87
+ READY gates. Retained revisions of that deployment share the Service, while a
88
+ replacement deployment receives a different Service so staging cannot rewrite
89
+ the existing production route. When replacement deployments request explicit
90
+ ports, their values must not collide while both deployments exist.
91
+
36
92
  ## Revision State
37
93
 
38
- `DeploymentSpec` is immutable. Promotion, rollback, suspension, resumption,
39
- and undeploy append immutable revisions. Reconcile writes mutable observed
40
- state separately.
94
+ `DeploymentSpec` is immutable. Its inference policy and full deployment contract
95
+ hash are copied into each immutable revision. Promotion, rollback, suspension,
96
+ resumption, and undeploy append revisions that retain that policy. Reconcile
97
+ writes mutable observed state separately.
41
98
 
42
99
  `READY` requires all three current-revision conditions:
43
100
 
@@ -50,6 +107,12 @@ The detail response includes `endpoints`. Cluster-local endpoints have
50
107
  when rollout hostname metadata exists. `available=true` means the current
51
108
  revision passed all READY gates.
52
109
 
110
+ Each endpoint advertises `inference_path=/v1/inference`, `docs_url`,
111
+ `openapi_url`, and `redoc_url`. When no reviewed host is available, the
112
+ NodePort endpoint returns corresponding URL templates instead. The Serving
113
+ OpenAPI document is generated for the deployed ModelArtifact and embeds the
114
+ effective model contract; it is not a generic platform API schema.
115
+
53
116
  Successful smoke verification is cached durably by revision, image digest,
54
- contract hash, and frozen lookup-test hash. A new revision or changed identity
55
- must run smoke again.
117
+ FeatureRetrieval contract hash, deployment contract hash, and frozen lookup-test
118
+ hash. A new revision or changed identity must run smoke again.
@@ -29,6 +29,22 @@ Use `get-deployment` to inspect the full revision history and endpoints. Use
29
29
  `list-deployments` for discovery and `get-deployment-events` for paginated
30
30
  audit evidence.
31
31
 
32
+ For direct model access, declare `service_exposure.type=NodePort` in the same
33
+ validated DeploymentSpec. After the revision is `READY`, read the observed
34
+ `nodeport` endpoint instead of constructing a Service name. Given an observed
35
+ base URL such as `http://<node-ip>:<node-port>`:
36
+
37
+ ```bash
38
+ curl http://<node-ip>:<node-port>/v1/model
39
+ curl http://<node-ip>:<node-port>/openapi.json
40
+ ```
41
+
42
+ Open `http://<node-ip>:<node-port>/docs` for that model's Swagger UI or
43
+ `http://<node-ip>:<node-port>/redoc` for ReDoc. The schemas describe the exact
44
+ deployed model. NodePort network reachability remains an environment concern;
45
+ do not report it as reachable unless `advertised_host` was reviewed and the
46
+ client can connect.
47
+
32
48
  ## Promotion And Approval
33
49
 
34
50
  ```bash
@@ -68,6 +84,47 @@ history; it is not equivalent to resume.
68
84
 
69
85
  ## Prediction
70
86
 
87
+ With a deployment-level inference policy, the request may use both deployment
88
+ defaults by omitting `horizon` and `output_window`:
89
+
90
+ ```json
91
+ {
92
+ "input_mode": "feature_lookup",
93
+ "cutoff_time": "2026-09-14T00:00:00+08:00",
94
+ "entity": {}
95
+ }
96
+ ```
97
+
98
+ To override the revision defaults, add either or both fields. This example keeps
99
+ the deployment horizon but returns its first day:
100
+
101
+ ```json
102
+ {
103
+ "input_mode": "feature_lookup",
104
+ "cutoff_time": "2026-09-14T00:00:00+08:00",
105
+ "entity": {},
106
+ "output_window": {
107
+ "start_offset": "0min",
108
+ "end_offset": "1d",
109
+ "boundary": "[start,end)"
110
+ }
111
+ }
112
+ ```
113
+
114
+ For the storage-power deployment that predicts eight days but returns only
115
+ next-day 00:15 through day-eight 24:00, use the deployment default or override
116
+ with `{"start_offset":"1d","end_offset":"8d","boundary":"(start,end]"}`.
117
+
118
+ Do not send `future_covariates` in `feature_lookup` mode. Serving derives the
119
+ declared known-future columns and full model prediction length from the
120
+ ModelArtifact, then the platform retrieves visible future Feature revisions.
121
+ Only those Features and their Parameter dependency closure are read; unrelated
122
+ historical Parameters in the same inference Manifest are not evaluated as
123
+ future inputs. Requested future Parameters must still provide trustworthy
124
+ `available_at <= cutoff_time` evidence.
125
+ For inline mode only, supply one row per model prediction step in
126
+ `inputs.future_covariates`.
127
+
71
128
  ```bash
72
129
  ml-platform --profile server predict-deployment <deployment-id> \
73
130
  /absolute/path/request.json
@@ -14,8 +14,37 @@ Interpret conditions before considering a reconcile:
14
14
  readiness through the platform/cluster diagnostic boundary.
15
15
  - `ArtifactsVerified=false`: the Serving `/model` identity does not match the
16
16
  revision, or the endpoint is unavailable.
17
+ - A NodePort endpoint with `url=null` is not a failed deployment. Kubernetes
18
+ assigned or will assign the port, but the DeploymentSpec did not declare a
19
+ reviewed `advertised_host`; use the returned `node_port` with a reachable
20
+ cluster node address.
21
+ - `/docs` or `/openapi.json` showing the wrong artifact identity indicates that
22
+ traffic is reaching a different Serving revision. Compare the document's
23
+ top-level `x-itsmp-model.artifact_id` with the observed DeploymentRevision.
17
24
  - `SmokePredictionPassed=false`: preserve the frozen package smoke request and
18
25
  error. Do not replace it with a current-time request to force success.
26
+ - `request horizon cannot override deployment inference_policy` or
27
+ `request output_window cannot override deployment inference_policy`: the
28
+ revision has `allow_request_override=false`; use equivalent values or create
29
+ a reviewed revision whose policy permits the required request behavior.
30
+ - `inference_policy output window must end within the configured horizon`:
31
+ override `horizon` and `output_window` together, or keep the deployment
32
+ defaults. A shorter horizon cannot retain a later default window.
33
+ - `feature_lookup obtains known future covariates from online retrieval`: remove
34
+ top-level `future_covariates`. Verify the columns belong to the bound
35
+ FeatureSet and their Parameters provide trustworthy `available_at` values.
36
+ - `availability_not_supported` or `available_at_missing` during future lookup:
37
+ publish a corrected Parameter/Feature dependency version with a source-field
38
+ or justified upper-bound availability contract; do not substitute caller data.
39
+ - `inference_policy horizon exceeds model maximum prediction length`: retrain
40
+ or select a model artifact with enough sequence steps. For `[1d,2d)` at
41
+ 15-minute frequency, the model needs 192 steps, not only the returned 96.
42
+ - An unexpected output point count usually indicates frequency/target-time
43
+ drift or an incomplete runtime trajectory. Inspect `output_window.boundary`,
44
+ UTC `start_time`/`end_time`, `point_count`, and the model sampling interval.
45
+ - If a right-closed deployment unexpectedly returns next-day 00:00 and omits
46
+ day-eight 24:00, check whether a request-level `output_window` omitted
47
+ `boundary`; omission intentionally falls back to `[start,end)`.
19
48
  - `SUPERSEDED`: operate on the active deployment leaf.
20
49
  - `SUSPENDED`: resume only with explicit authorization and a reason.
21
50
  - `UNDEPLOYED`: create a governed deployment or rollback as supported; resume
@@ -32,6 +32,7 @@ to discover fields. Preserve release/error evidence when deployment differs.
32
32
  - Before submission, show the exact JSON path, immutable identities, expected workload, and target API. Obtain explicit authorization. Retry and cancel require separate authorization for the exact Job.
33
33
  - Never use `latest` image tags. During development TrainerDefinition stays at `v1`; rebinding it follows the reviewed release procedure and requires confirming no active Job references the old definition.
34
34
  - A succeeded Job is insufficient evidence. Training requires a valid ModelArtifact and signature; evaluation requires immutable Result/Summary evidence and coverage; packaging requires `READY`, an immutable image digest, manifest, and passing test report.
35
+ - Register a ModelArtifact through `register-model-artifact` only after a platform-generated PASS evaluation/result or summary has complete evidence; do not bypass the CLI with a direct registration HTTP request.
35
36
  - Do not register caller-computed evaluation results. Workers produce predictions, metrics, decisions, and summaries from frozen DatasetArtifact rowsets.
36
37
  - Keep credentials, registry secrets, Kubernetes details, and model binaries out of request JSON and reports.
37
38
 
@@ -24,6 +24,14 @@ do not guess registries or pass deployment secrets. A mismatch needs the approve
24
24
  runtime contract, not repeated package versions. Unknown request keys return 422; do not add `runtime`, `image`, or `resources`
25
25
  fields. Inspect the returned resolved package.
26
26
 
27
+ Chronos-2 LoRA packages also require exactly one platform-managed
28
+ `chronos2-checkpoint` runtime artifact for the selected trainer/device binding.
29
+ It must set `DATA_PLATFORM_CHRONOS2_MODEL_PATH`; otherwise
30
+ `validate-model-package` fails before a Kubernetes Job is created. Cache-hit
31
+ messages for `adapter_model.safetensors` or `model.chronos2` do not prove that
32
+ the base checkpoint is present. Full fine-tuned Chronos-2 artifacts contain
33
+ their complete weights and do not require this external checkpoint.
34
+
27
35
  `input_modes` must be unique, include `inline`, and may additionally include
28
36
  `feature_lookup` or `tabular_forecast` only when supported by the selected
29
37
  runtime. `feature_lookup` still requires artifact lineage
@@ -31,6 +39,17 @@ runtime. `feature_lookup` still requires artifact lineage
31
39
  signature. Do not infer either capability from training success.
32
40
  Omit rather than use an empty list to request default inline behavior.
33
41
 
42
+ Register a validated artifact only after a platform-generated evaluation result or
43
+ summary is `PASS`, `COMPLETE`, and belongs to the same artifact:
44
+
45
+ ```bash
46
+ ml-platform --profile server register-model-artifact <artifact-id> \
47
+ --evaluation-id <evaluation-result-or-summary-id>
48
+ ```
49
+
50
+ The API performs the complete registration gate. Do not replace this command with
51
+ a direct `POST /models/{artifact_id}/register` request.
52
+
34
53
  For `feature_lookup`, the package request must bind both the exact retrieval
35
54
  contract and a sanitized real lookup test. They are immutable package identity,
36
55
  not namespace Secret/ConfigMap settings:
@@ -74,6 +93,11 @@ not namespace Secret/ConfigMap settings:
74
93
  The inference DatasetManifest must exist with the supplied hash and use
75
94
  `mode=inference`. Its FeatureSet, stable contract signature, adapter/temporal
76
95
  hashes, entity keys, and row/context parameters must match the ModelArtifact.
96
+ The package-bound signature remains the Serving binding identity. Online fetch
97
+ responses may also report an independently resolved execution signature for
98
+ diagnostics; database principals are excluded from new stable signatures, so
99
+ credential rotation or distinct read-only workload accounts do not alter the
100
+ model data contract.
77
101
  The test cutoff must include a timezone. A legacy feature-lookup package missing
78
102
  either package-bound field remains readable but cannot be rerun or deployed;
79
103
  create a new package version.
@@ -169,10 +169,12 @@ and `data.labels` must use that same output-label order:
169
169
  Every target and covariate must be a numeric Feature. `past_only` is available
170
170
  only through the cutoff. `known_future` must be represented in training by the
171
171
  forecast or schedule available at that historic cutoff, never by a later actual
172
- observation. At runtime callers provide one finite numeric value for every
173
- `known_future` column and every prediction step. The current contract validates
174
- the names, values, and row count; retain forecast issue/availability lineage in
175
- the upstream Feature data when revisions must be audited.
172
+ observation. At runtime inline callers provide one finite numeric value for
173
+ every `known_future` column and every model prediction step. In
174
+ `feature_lookup` mode, callers provide none: Serving requests the declared
175
+ Feature columns from the deployment-bound FeatureSet, and the platform selects
176
+ future event rows whose revisions satisfy `available_at <= cutoff_time`.
177
+ Retain forecast issue/availability lineage in the upstream Feature data.
176
178
 
177
179
  ## TrainingJobRequest and identity propagation
178
180
 
@@ -243,6 +245,16 @@ aligned horizons up to that maximum and returns the corresponding trajectory
243
245
  prefix; it rejects unaligned or longer horizons. A one-step model remains a
244
246
  scalar response.
245
247
 
248
+ When a deployment must use cutoff at today's 00:00 and return only tomorrow's
249
+ 00:00 through the following 00:00, train for the complete interval from cutoff
250
+ to the output end. At 15-minute frequency, deployment horizon `2d` means
251
+ `prediction_length=192`; output window `[1d,2d)` then projects the second 96
252
+ points. Chronos-2 known-future covariates must still contain all 192 rows. In
253
+ `feature_lookup` mode the platform retrieves those rows even when the request
254
+ overrides the returned window; inline requests must still carry them. A
255
+ 150-step artifact cannot serve this contract and must be retrained rather than
256
+ having its response window stretched at deployment time.
257
+
246
258
  `gap_policy=fill` requires `padding_policy=edge` or `zero`; non-fill requires
247
259
  `padding_policy=none`. Filling changes model inputs and needs an intended
248
260
  business policy. `skip` and padding are not automatic fixes for rejected grids.
@@ -93,15 +93,18 @@ the ordered target/output-label pairs; see [training-contracts.md](training-cont
93
93
  for the complete JSON fragment.
94
94
 
95
95
  Training records must contain the forecast that was available at each historic
96
- cutoff, not actual weather observed later. At online inference, pass one numeric
97
- row per forecast step using the Serving runtime, not `fetch-inference-data`:
96
+ cutoff, not actual weather observed later. Invoke the Serving runtime, not
97
+ `fetch-inference-data`:
98
98
 
99
99
  ```bash
100
100
  ml-platform predict-model /absolute/path/to/inference-request.json \
101
101
  --serving-url https://storage-forecast.example
102
102
  ```
103
103
 
104
- For `input_mode=inline`, put those rows in `inputs.future_covariates`. For
105
- `input_mode=feature_lookup`, put them in the top-level `future_covariates`.
106
- Their column names must exactly match the adapter's `known_future` covariates,
107
- and their count must equal the trained `prediction_length`.
104
+ For `input_mode=inline`, put one row per trained prediction step in
105
+ `inputs.future_covariates`; names must exactly match the adapter's
106
+ `known_future` columns. For `input_mode=feature_lookup`, do not send future
107
+ rows. Serving asks the platform for the declared columns and full
108
+ `prediction_length`; the Features must belong to the deployment-bound
109
+ FeatureSet, and their source revisions must satisfy
110
+ `available_at <= cutoff_time` even though their event times are later.