@zhuoyuezs/ml-platform 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +7 -3
  2. package/package.json +1 -1
  3. package/checksums.json +0 -155
  4. package/release.json +0 -52
  5. package/runtime/business-client/README.md +0 -78
  6. package/runtime/business-client/package-lock.json +0 -19
  7. package/runtime/business-client/package.json +0 -23
  8. package/runtime/business-client/src/catalog.js +0 -206
  9. package/runtime/business-client/src/cli.js +0 -533
  10. package/runtime/business-client/src/config.js +0 -56
  11. package/runtime/business-client/src/http.js +0 -254
  12. package/skills/feature-management/SKILL.md +0 -480
  13. package/skills/feature-management/agents/openai.yaml +0 -4
  14. package/skills/feature-management/assets/catalog-template/catalog.json +0 -23
  15. package/skills/feature-management/assets/catalog-template/datasets/example_temperature_training.v1.json +0 -40
  16. package/skills/feature-management/assets/catalog-template/feature_sets/example_temperature_core.v1.json +0 -14
  17. package/skills/feature-management/assets/catalog-template/features/example_temperature_mean_5m.v1.json +0 -28
  18. package/skills/feature-management/assets/catalog-template/operator_package/pyproject.toml +0 -12
  19. package/skills/feature-management/assets/catalog-template/operator_package/src/business_feature_operator_template/__init__.py +0 -39
  20. package/skills/feature-management/assets/catalog-template/operator_package/tests/test_operator.py +0 -83
  21. package/skills/feature-management/assets/catalog-template/operators/example_temperature_features.v1.json +0 -58
  22. package/skills/feature-management/assets/catalog-template/parameters/example_temperature.v1.json +0 -58
  23. package/skills/feature-management/references/commands.md +0 -358
  24. package/skills/feature-management/references/contracts.md +0 -731
  25. package/skills/feature-management/references/operator-authoring.md +0 -175
  26. package/skills/feature-management/references/platform-capability-guide.md +0 -75
  27. package/skills/feature-management/references/supervised-datasets.md +0 -101
  28. package/skills/model-lifecycle-management/SKILL.md +0 -38
  29. package/skills/model-lifecycle-management/agents/openai.yaml +0 -4
  30. package/skills/model-lifecycle-management/references/discovery.md +0 -89
  31. package/skills/model-lifecycle-management/references/evaluation.md +0 -172
  32. package/skills/model-lifecycle-management/references/packaging.md +0 -56
  33. package/skills/model-lifecycle-management/references/training-contracts.md +0 -164
  34. package/skills/model-lifecycle-management/references/training.md +0 -85
@@ -1,480 +0,0 @@
1
- ---
2
- name: feature-management
3
- description: Manage projects, versioned business feature assets and their lifecycle, dataset rowsets and endpoint eligibility, and causal realtime row or sequence-context reads through the deployed ML Platform API using the ml-platform CLI installed with the same release. Use when a business user asks an agent to manage an empty Project, define or change Parameter source contracts, author/package/register an Operator wheel, define single-column Features, order a FeatureSet, create a DatasetManifest or catalog, inspect references, soft-delete or restore a Parameter/Feature/FeatureSet version, configure training/validation/test rowsets or abnormal-data endpoint exclusion, configure realtime freshness policy, run catalog dry-run/apply, build a dataset, fetch inference data, or inspect an artifact without downloading the platform source repository. Do not use for model training, Operator/Dataset deletion, image builds, or Kubernetes deployment.
4
- ---
5
-
6
- # Feature Management
7
-
8
- Build the public asset chain without bypassing its versioned contracts:
9
-
10
- ```text
11
- Parameter -----> Feature
12
- Operator ------> Feature -> FeatureSet -> DatasetManifest -> DatasetArtifact
13
- ```
14
-
15
- Treat `Recipe` and public `Feature.compute` as removed. Treat `computation_hash` as internal execution metadata, never as a business-managed asset.
16
-
17
- ## Platform Role And Evidence Boundaries
18
-
19
- The ML Platform is a deterministic data-contract and data-delivery platform. It
20
- registers versioned source Parameters, runs approved deterministic Operators,
21
- orders single-column Features into FeatureSets, resolves DatasetManifests, and
22
- materializes batch DatasetArtifacts or serves one causal realtime inference row.
23
- It records versions, lineage, quality, missingness, freshness, and execution
24
- metadata so an algorithm project can consume data without owning source routing
25
- or cache details.
26
-
27
- This Skill does not train, evaluate, or serve models; own complete business feature
28
- engineering; provision arbitrary source tables; or administer Kubernetes and
29
- platform services. Training, evaluation and model packaging are handled by the
30
- separate `model-lifecycle-management` Skill; this scope limit is not a claim that
31
- the platform lacks those capabilities. Read
32
- [references/platform-capability-guide.md](references/platform-capability-guide.md)
33
- when the user needs the detailed platform boundary or evidence-level explanation.
34
-
35
- Keep these evidence rules active in every workflow:
36
-
37
- - Platform defaults and capabilities are not business evidence.
38
- - Dry-run, publish, resolve, build, metadata inspection, downloaded-file
39
- inspection, and realtime fetch are separate evidence checkpoints; success at
40
- one checkpoint does not imply success at the next.
41
- - `validation.ok=true` does not by itself prove source semantics, causal formula
42
- correctness, Parquet contents, or numeric parity.
43
- - Dry-run, publish, and resolve may not detect a missing source relation. Do not
44
- report source-backed success until build/fetch returns the required evidence,
45
- and never rename a Parameter or remove fields merely to bypass a failed read.
46
-
47
- ## Load The Right Context
48
-
49
- 1. Resolve the Skill root as the directory containing this `SKILL.md`.
50
- 2. Read [references/contracts.md](references/contracts.md) before creating or changing JSON assets.
51
- 3. Read [references/operator-authoring.md](references/operator-authoring.md) whenever creating or changing Operator code or a wheel.
52
- 4. Read [references/commands.md](references/commands.md) immediately before a platform CLI action: discovery, validation, publication, build, realtime fetch, or artifact download. A local-only draft that is forbidden to call the CLI does not need this reference.
53
- 5. Use [assets/catalog-template](assets/catalog-template) as a copyable starting point for a new end-to-end catalog. Rename every `example_*` identifier and update every referenced path before validation.
54
- 6. Read [references/platform-capability-guide.md](references/platform-capability-guide.md) only when selecting an asset type or explaining a platform capability. Do not load it merely to write a confirmed local draft; it is never evidence for unresolved business semantics.
55
-
56
- ## Initialize The Client
57
-
58
- Use the `ml-platform` executable on `PATH` for every platform command. The formal npm release installs
59
- the CLI and this pure Skill together. The Skill does not contain a second CLI runtime, launcher, or
60
- installer. During repository development, provide the current JavaScript CLI through an isolated test
61
- `PATH`.
62
-
63
- Before any platform operation, verify the executable and its version:
64
-
65
- ```bash
66
- command -v ml-platform
67
- ml-platform version
68
- ```
69
-
70
- If the executable is missing or cannot start, stop and report that the ML Platform release installation is incomplete. Do not download a client, search for a repository checkout, or fall back to another executable.
71
-
72
- Before any server-profile discovery, dry-run, publication, build, or artifact
73
- operation, inspect the effective API configuration:
74
-
75
- ```bash
76
- ml-platform show-config
77
- ml-platform --profile server health
78
- ```
79
-
80
- Use the global `--profile server` form shown above, before the business
81
- command. Do not append `--profile` after a business command. Before discovery,
82
- check the installed release with `ml-platform --help` and the relevant
83
- subcommand's `--help`; CLI releases may differ in supported flags. In the
84
- deployed 0.6.x CLI, registry `list-*` commands emit JSON by default and do not
85
- accept a `--json` flag.
86
-
87
- If the installed release rejects the global `--profile server` form shown above,
88
- record the CLI syntax error and inspect `show-config`/subcommand help before
89
- retrying the same read-only command without that flag when supported. Do not
90
- switch clients or classify a syntax error as an API outage; keep each command
91
- separate so CLI compatibility remains distinguishable from network health.
92
-
93
- The effective API target is resolved in this order: explicit `--api-url`,
94
- `ML_PLATFORM_API_URL`, then the saved value written by `ml-platform configure`.
95
- If no target is configured, ask the user for an approved API URL before making
96
- server requests. Do not hardcode an environment-specific address in a Skill,
97
- catalog, or prompt. Keep database, MinIO, and source credentials out of commands;
98
- use the server's managed Secrets.
99
-
100
- Install and upgrade the CLI and Skill only through the explicit commands provided by `@zhuoyuezs/ml-platform`. Restart the Agent session after a successful Skill upgrade so the definition is reloaded. Never copy files over an installed Skill directory manually.
101
-
102
- ## Establish Intent
103
-
104
- Collect only missing information. Do not invent a source table, source field, formula, time boundary, unit, valid range, missing-data rule, or owner.
105
-
106
- Confirm:
107
-
108
- - the target project (namespace) for the assets; use the built-in `default` only when the user has no dedicated project. After the target is confirmed, write its explicit `project` field in every Parameter, Operator, Feature, FeatureSet and DatasetManifest draft; never rely on the schema default. Reads and filters use the `--project` command option;
109
- - business meaning, stable asset names, owner, and intended consumers;
110
- - Parameter source adapter (`postgresql_direct`, `mysql_direct`,
111
- `sqlserver_direct`, or `influxdb_direct`) and credential-free source mapping;
112
- - feature formula, exact Parameter dependencies, windows, inclusion rules, rounding, null behavior, and output dtype;
113
- - whether an approved Operator already implements the formula;
114
- - FeatureSet column order;
115
- - dataset mode, read policy, time range, grid, prediction horizon/cutoff contract, and explicit Parameter outputs;
116
- - named training/validation/test rowsets, abnormal windows, endpoint-policy scope,
117
- and the model context lookback used to decide endpoint eligibility;
118
- - realtime freshness and missing-input policy when serving inference data;
119
- - target profile/API and whether the user authorizes publish and/or build actions.
120
-
121
- Separate preparation from mutation. Creating files and running local tests or `apply --dry-run` does not authorize publishing a wheel, changing the Registry, or submitting a build Job.
122
-
123
- Soft-delete and restore are separate Registry mutations. Before soft-deleting a
124
- Parameter, Feature, or FeatureSet version, inspect its lifecycle state and both
125
- direct and transitive references, report the affected immutable consumers, and
126
- obtain explicit authorization for the exact `project/name:version`. Supply an
127
- actor, reason, and stable idempotency key. Soft deletion preserves historical
128
- references and hashes but hides the version from normal discovery and prevents
129
- new consumers from binding it. Restore only after checking that all of the
130
- resource's own dependencies are active. Never describe these operations as
131
- physical deletion.
132
-
133
- A label such as "10-minute mean" confirms neither its input Parameter nor a
134
- complete formula. Before drafting an Operator or Feature, ask for the exact
135
- versioned input Parameter(s), or for an approved source contract from which
136
- they will be created. Do not infer an input from the Feature name or a similar
137
- existing asset.
138
-
139
- ### Semantic Asset Review Gate
140
-
141
- Treat resource correctness as a separate gate from workflow correctness. Before
142
- creating Catalog JSON, write a local semantic asset review with one row per
143
- Parameter, Operator, Feature and Dataset field:
144
-
145
- ```text
146
- asset_key | business_meaning | source/evidence | confirmed_by | unresolved | proposed_value
147
- ```
148
-
149
- The review must distinguish three sources: confirmed business facts, facts
150
- observed from the selected Project Registry/CLI, and agent proposals. A Skill
151
- reference, schema default, similarly named old asset, or platform capability is
152
- not business evidence. Do not convert a proposal into `proposed_value` without
153
- explicit user confirmation or an exact match in the selected Project.
154
-
155
- Stop with `need_business_confirmation` when any required source mapping, field,
156
- unit, formula, time conversion, missing/quality policy, FeatureSet order,
157
- dataset read policy, rowset/endpoint policy, owner, or approval boundary is
158
- unresolved. Do not create placeholder Catalog files to make the workflow look
159
- complete.
160
-
161
- For a requested Feature, `exact Parameter dependencies` is an independent
162
- required contract item. If the user names a transform or window but not its
163
- input Parameter(s), include `input_parameter` in the unresolved questions and
164
- stop. Do this before treating an Operator formula as complete: a time window,
165
- cutoff rule, or Feature name never identifies the input.
166
-
167
- After confirmation, show the proposed dependency closure and obtain approval of
168
- the semantic asset plan before generating Catalog files. A successful local
169
- schema check or remote dry-run is not semantic approval.
170
-
171
- Before emitting or writing a draft, mechanically check that every asset carries
172
- the confirmed `project` field, that every Feature input carries that same
173
- `project`, and that every Operator `input_schema.parameters` reference is
174
- qualified as `project/parameter:version`. The schema's `default` values are not
175
- valid substitutes for an explicit non-default target. When a confirmed Feature
176
- config defines window closure, cutoff inclusion, duplicate handling, or empty
177
- window behavior, copy all of those fields into the Feature config rather than
178
- reducing it to the window string.
179
-
180
- ## Discover Existing Assets
181
-
182
- Check the selected profile and list existing Parameter, Operator, Feature, FeatureSet, and Dataset versions before choosing names. Scope discovery to the target project with `--project`, because the true registry key is `project/name:version` and the same `name:version` may exist independently under another project. Run each `list-*` command as a separate command so one failed check cannot hide the status of the others. Do not add `--json` unless the installed subcommand help explicitly advertises it; supported releases emit machine-readable JSON by default. Registry list commands are paginated; search by stable identifier or follow every page until `offset + len(items) >= total`. Reuse an exact immutable version only when its full content matches. Never reference an asset in another project; cross-project references are rejected.
183
-
184
- CLI readiness is a hard gate for every Registry conclusion. If `command -v`,
185
- `version`, `show-config`, or server `health` fails, returns a nonzero status, or
186
- does not identify the intended target, stop with `platform_not_ready`. Do not
187
- list assets, select reuse versus authoring, dry-run, publish, build, fetch, or
188
- report a Registry fact from prompt text, a remembered response, or a similar
189
- local asset. Report the failed command and its configured target; resume only
190
- after the user/environment restores the same target.
191
-
192
- Create a new version when source semantics, formula code, config meaning, inputs, output dtype, time behavior, quality rules, or column order change. Never overwrite an immutable version or use suffixes such as `new`, `final`, or `test2`.
193
-
194
- ### Operate An Existing Registered Dataset
195
-
196
- For diagnosis, resolve, build, Job lookup, and artifact lookup of an already
197
- registered DatasetManifest, use the API through `ml-platform`. Do not search the
198
- platform source checkout or a local Catalog directory for a matching JSON file.
199
-
200
- 1. Run `show-config` and `health` to record the effective API source.
201
- 2. Run `list-projects`, then `list-datasets --project <project>` to discover
202
- candidates from the Registry.
203
- 3. Ask the user to confirm the exact `project`, `dataset_id`, and
204
- `dataset_version` when more than one valid candidate exists. Never infer a
205
- target from a similar local filename.
206
- 4. Run `get-dataset <dataset_id> <dataset_version> --project <project>` and
207
- inspect the returned registered contract.
208
- 5. Run `resolve-dataset` for a read-only dependency and manifest-hash check.
209
- 6. Submit exactly one `build-registered-dataset ... --wait` only after the user
210
- 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
-
214
- Local `resolve-manifest` and `build-dataset <file>` remain authoring tools for a
215
- new or changed Catalog contract before it is registered. They are not required
216
- for operating an existing Registry version.
217
-
218
- ## Upgrade Dependency Chains
219
-
220
- Treat a version change as a release of its affected reverse-dependency closure, not as an isolated asset bump.
221
-
222
- 1. Record the intended old-to-new version mapping and the semantic reason for every changed asset.
223
- 2. Follow exact references from the changed asset through every affected downstream consumer. For a Parameter change, publish a new Operator version when its input schema names that Parameter version, then new versions of every affected Feature, FeatureSet, and DatasetManifest. For an Operator change, start with its affected Features.
224
- 3. Republish only the affected closure, but explicitly list and justify every downstream asset intentionally retained on an older dependency.
225
- 4. Keep every reference exact. Never rewrite an existing immutable version, infer `latest`, or assume that increasing a Feature or FeatureSet version also upgrades its dependencies.
226
- 5. Treat `apply --dry-run` as an existence and structural-compatibility check. It does not prove that the declared versions are the intended business release.
227
-
228
- Use this dependency order for an affected chain:
229
-
230
- ```text
231
- Parameter -> Operator -> Feature -> FeatureSet -> DatasetManifest
232
- ```
233
-
234
- ## Build The Catalog
235
-
236
- Keep one business domain in one user-owned catalog directory:
237
-
238
- ```text
239
- <catalog>/
240
- catalog.json
241
- parameters/
242
- operators/
243
- operator_package/
244
- features/
245
- feature_sets/
246
- datasets/
247
- ```
248
-
249
- Keep platform demos and V95 built-ins unchanged. Do not put unrelated business assets under `src/data_platform_demo/builtin_catalogs/v95`.
250
-
251
- ### Define Parameters
252
-
253
- Use the platform-capability guide's asset table before choosing the resource
254
- type. For each Parameter record the business signal, exact source evidence,
255
- unit, time/availability semantics and missing policy in the semantic review.
256
- Never infer a source table, column, measurement, tag, unit or timezone from a
257
- Parameter name.
258
-
259
- Create one stable, versioned source contract for each independently readable value. Keep credentials out of JSON. Use only supported direct adapters (`postgresql_direct`, `mysql_direct`, `sqlserver_direct`, and `influxdb_direct`) and explicit source identity. The server supplies database DSNs from managed Secrets; never add them to CLI arguments or Catalog JSON. Put source data validity in `quality_rules`; put dataset-specific transformations in preprocess Operators.
260
-
261
- When the approved source contract supplies SQL, copy its query text and named
262
- parameters exactly into `source.sql`/`source.params`. Do not retype, beautify,
263
- rename an identifier, change a join key, or "simplify" an approved query while
264
- drafting. SQL whitespace may be formatted only when a reviewed formatter proves
265
- the token stream is unchanged; every source identifier and `<= %(end)s` boundary
266
- remains part of the Parameter contract.
267
-
268
- For SQL Parameters, the runtime contract is a single statement: use the exact
269
- `source.sql` field and a mapping under `source.params` for every named
270
- placeholder other than the reserved `start` and `end` window parameters. Do not
271
- use `source.parameters` (it is not a supported alias and may be silently
272
- dropped by older CLI/server releases). Do not leave a trailing semicolon; the
273
- deployed Worker rejects SQL containing multiple statements. Verify the resolved
274
- Parameter still contains the named params before authorizing a build.
275
-
276
- Use Parameter `rounding` when every consumer must receive the same fixed-point value. The platform applies `mode` (`half_up` or `half_even`) and `decimals` after source normalization and before quality checks, source caching, replay, and Operator execution. Prefer an unrounded source expression, do not repeat the same rounding in an Operator, and publish a new Parameter plus its affected reverse-dependency closure when the rule changes.
277
-
278
- Do not represent a rolling mean, lag, ratio, trend, or model input as a Parameter. Those are Features.
279
-
280
- ### Define Operators
281
-
282
- First reuse a registered Operator if its version, input schema, output schema, formula semantics, and runtime contract match exactly.
283
-
284
- When a new Operator is required:
285
-
286
- 1. Write a standalone pure-Python package with a `module:function` entrypoint.
287
- 2. Make the Feature entrypoint accept one context and return a pandas DataFrame.
288
- 3. Consume only declared `context.inputs` and `context.metric_frames`.
289
- 4. Return `event_time` exactly equal to `context.target_times` plus the requested physical output columns.
290
- 5. Implement explicit causal boundaries; never use future rows accidentally.
291
- 6. Keep execution deterministic, network-free, credential-free, and bounded by `timeout_seconds`.
292
- 7. Add formula, boundary, missing-value, requested-output, and ordering tests.
293
- 8. Build a `py3-none-any` wheel and reference it from `catalog.json`.
294
- 9. Leave `code_hash`, `package_uri`, and `code_artifact` null in the draft spec; catalog publication fills them from the uploaded wheel.
295
-
296
- Use a meaningful immutable `function_hash`. Change the Operator version whenever executable behavior changes.
297
-
298
- ### Define Features
299
-
300
- Create one JSON file per single output column. Set the confirmed `project` on the
301
- Feature and on every nested Feature input; a FeatureInput without `project`
302
- silently targets `default`. Bind exactly one Operator version and physical
303
- `output_column`. List only the Parameter versions actually required by that
304
- column's formula.
305
-
306
- Features may share the same Operator and config. The planner will merge their exact inputs and call the Operator once per computation group. Do not duplicate every Operator input into every Feature merely to make schemas look uniform.
307
-
308
- ### Define The FeatureSet
309
-
310
- Reference immutable Feature versions in the exact consumer column order. Keep the list nonempty and duplicate-free. Do not copy formulas, inputs, or Operator configuration into the FeatureSet.
311
-
312
- ### Define The DatasetManifest
313
-
314
- For supervised datasets, read
315
- [references/supervised-datasets.md](references/supervised-datasets.md) before
316
- publishing the first version. Settle labels, clocks, split bindings and the final
317
- DataSchema before expensive training.
318
-
319
- Do not use DatasetManifest as a catch-all for unresolved semantics. Confirm the
320
- dataset purpose and consumer, then separately confirm the target grid, horizon,
321
- read policy, explicit Parameter outputs, rowset or rowset splits, abnormal windows and
322
- endpoint eligibility. Keep the semantic asset review beside the draft Catalog
323
- so a reviewer can compare business decisions with generated fields.
324
-
325
- Reference exactly one FeatureSet. Use `parameters` only for Parameter columns that must also appear explicitly in `parameter_dataset.parquet`; Feature dependencies are resolved automatically.
326
-
327
- Map the current Manifest schema exactly rather than carrying descriptive fields
328
- from Parameter, Feature, or FeatureSet into it. A target Parameter reference is
329
- **nested**; never flatten its `version` or `project` onto `target`:
330
-
331
- ```json
332
- "target": {
333
- "parameter": {"parameter": "hot_metal_si", "version": "v1", "project": "<project>"},
334
- "si_time_source": "dispatch_time",
335
- "offset_minutes": 20,
336
- "interpolation": {"method": "linear"}
337
- }
338
- ```
339
-
340
- `target.interpolation` is `{"method": "linear"}`, `{"method": "none"}` or
341
- `{"method": "forward_fill"}` -- neither it nor `target.parameter` accepts a
342
- bare string. The current DatasetManifest has no top-level `owner`,
343
- `description`, `si_null_policy`, or `preserve_all_candidate_rows`. Map a
344
- business statement only to an existing schema field (for example `mark_only`,
345
- `endpoint_policy`, a Feature config, or a Parameter missing policy); otherwise
346
- keep it in the semantic review and ask for a platform/schema change. Validate
347
- the generated object against the current schema before running `apply --dry-run`.
348
-
349
- When a confirmed missing-data policy applies to a Feature-only Parameter, put it
350
- in `parameter_missing_policies`, using `parameter`, `version`, `project`, and
351
- `policy`. Do not copy the `ParameterRequest` names `name` and `missing_policy`
352
- into that list. Omit the section when no such policy is confirmed.
353
-
354
- Declare one dataset-wide `prediction` contract when Features use a forecast cutoff. Operators consume `context.cutoff_times`; do not copy the same prediction horizon into every Feature config. Check the selected Operator's `input_schema.prediction` limits and satisfy an explicit-horizon requirement before publishing or building.
355
-
356
- Use `snapshot` for reproducible training data, `as_of` for historical visibility replay, and `latest` for current inference-style reads. Use a fresh `dataset_version` when validating a new release or intentionally requesting a new immutable dataset contract.
357
-
358
- Treat row construction and endpoint eligibility as separate contracts. Use
359
- `rowset_splits` to label candidate target instants such as `training`,
360
- `validation`, and `test`. When abnormal observations should make only selected
361
- endpoints unusable, keep `abnormal_windows.policy=mark_only` and declare
362
- `endpoint_policy`; do not delete canonical Feature rows. Declare
363
- `endpoint_policy.context_lookback` from the model sequence contract, independently
364
- of Operator source-history requirements. Read [references/contracts.md](references/contracts.md)
365
- for the cutoff formula, half-open overlap boundaries, scope behavior, and
366
- `rowset_membership.parquet` schema.
367
-
368
- For realtime inference, declare `realtime_fetch` only when its effective policy
369
- must be part of the contract; leaving it unset preserves existing manifest
370
- hashes. Keep `allow_missing=false` unless the user explicitly accepts missing
371
- required inputs. Read [references/contracts.md](references/contracts.md) for the
372
- freshness, tail-edge, gap-fill, and rowset contracts.
373
-
374
- ## Validate Before Publishing
375
-
376
- Run, in order:
377
-
378
- 1. Semantic asset review: no required unresolved field and every proposed value has a source or user confirmation.
379
- 2. Operator unit tests. Before building, turn every applicable item in
380
- `operator-authoring.md` into a separately named test; do not let one broad
381
- happy-path assertion substitute for cutoff-before/at/after, duplicate and
382
- missing input, empty history, requested-output, event-time order, or
383
- dtype/rounding coverage. The template is only a starting point.
384
- 3. Wheel build and wheel filename verification.
385
- 4. Catalog path, schema, dependency, immutability, and package validation with `apply --dry-run` against the same target profile intended for publication.
386
- 5. Compare the catalog's exact dependency closure with the intended old-to-new version mapping. Reject any affected downstream reference that still points to an old version unless its retention is explicit and justified.
387
- 6. A human-readable summary of planned new, unchanged, retained, and conflicting assets.
388
-
389
- Stop on any error. Do not weaken schema validation, fabricate a missing dependency, change an existing version in place, or switch profiles to make validation pass.
390
-
391
- ## Publish And Build
392
-
393
- Publish only after the user explicitly approves Registry and wheel changes. Use catalog `apply` so publication follows Parameter -> Operator -> Feature -> FeatureSet -> Dataset order.
394
-
395
- After publication, resolve every new DatasetManifest and compare its exact Parameter, Operator, Feature, and FeatureSet versions with the pre-publication mapping. Stop if an affected old key or any unexpected version remains. Resolve the manifest before building. Submit a build only when requested. For the current partitioned materialization runtime, use `--max-parallelism 1` unless a separately verified platform capability says otherwise; do not retry or resubmit a failed Job until its error and already-completed partitions are understood. For server builds, wait for the terminal Job state and download the exact artifact by `dataset_id + manifest_hash`.
396
-
397
- Do not delete versioned Registry assets, cancel Jobs, rebuild images, modify Kubernetes, or change service configuration as part of this workflow unless the user separately and explicitly requests that action. An empty Project may be soft-deleted only on an explicit request; rely on the server to reject deletion when resources still exist.
398
-
399
- ## Fetch Realtime Inference Data
400
-
401
- Use `fetch-inference-data` only when the user requests one causal-cutoff read.
402
- Confirm the cutoff and prediction horizon. The command must call
403
- `POST /inference-data/fetch`; it must not submit a batch build, write parquet, or
404
- publish a DatasetArtifact.
405
-
406
- Verify that the response reports the requested cutoff and derived target time,
407
- `uses_post_cutoff_data=false`, `contract.manifest_hash`, a replayable `as_of`
408
- manifest, and per-Parameter freshness evidence. Report tolerated missing or
409
- gap-filled inputs as degraded freshness, not as a normal read.
410
-
411
- ## Verify The Artifact
412
-
413
- Treat Registry metadata inspection and downloaded-file inspection as separate
414
- checkpoints. A successful `get-dataset-artifact` can establish the immutable
415
- identity, object inventory, row count, validation summary, and lineage metadata;
416
- it cannot establish Parquet schema, column order, or file-content hashes. If a
417
- download times out, report whether no response/progress was observed or whether
418
- some body bytes were received, preserve the metadata-only evidence, and leave
419
- downloaded-file validation explicitly incomplete.
420
-
421
- Require all of the following before reporting success:
422
-
423
- - Job status is `succeeded`;
424
- - `validation.json` has `ok: true` and no errors;
425
- - `validation.feature_nulls` is read, not skipped: `ok: true` can coexist with
426
- null model inputs reported as warnings. Report `total_null_cells`, and for each
427
- affected Feature its `null_count`, event-time range, and upstream Parameter
428
- keys. Set `output.strict_feature_nulls` when any null should fail the build
429
- instead;
430
- - row count is nonzero and matches the requested half-open time grid when no
431
- documented row filtering applies. When `abnormal_windows` uses a drop policy,
432
- reconcile the lower count against `abnormal_windows.rows_before`,
433
- `rows_after`, and `dropped_rows` in the resolved manifest. With `mark_only`,
434
- require `dropped_rows=0` and preserve the full candidate rowset;
435
- - when `endpoint_policy` is set, require `abnormal_windows.policy=mark_only`,
436
- preserve every candidate row in `feature_dataset.parquet` and
437
- `parameter_dataset.parquet`, and require `rowset_membership.parquet`;
438
- - verify membership counts globally and by rowset, inspect every ineligible
439
- row's `reason_codes`, and confirm that the configured compatibility column in
440
- both canonical datasets equals `policy_applied AND eligible`; it is false for
441
- pass-through rowsets outside the policy scope;
442
- - for a partitioned build, verify that merged membership, endpoint-policy
443
- quality statistics, lineage, and `policy_hash` match a single build of the
444
- same manifest;
445
- - `feature_dataset.parquet` starts with `event_time`, optional `furnace_id`, then FeatureSet columns in exact order;
446
- - resolved lineage records every Parameter version, Feature version, Operator version, code hash, and computation hash, exactly matches the approved dependency-version mapping, and contains no stale affected key;
447
- - artifact lineage contains the same approved dependency closure as the resolved manifest;
448
- - execution metadata shows the expected number of computation groups and requested physical columns;
449
- - when `source_read` is set, `latency_stats.fetch_timing_summary` shows the chunk
450
- windows tiling the fetch range, and any retries are accounted for;
451
- - missing values and warnings are reported, not silently repaired.
452
-
453
- The manifest hash returned by `resolve-manifest` or `resolve-dataset` is the artifact key: it stays
454
- the same after the build, so it is usable for cache reuse and polling before
455
- submission. Distinguish the two lookup failures rather than treating both as "not
456
- ready" — `422` with `invalid_artifact_key` means the key can never name an
457
- artifact, while `404` with `artifact_not_found` or `artifact_not_built` means
458
- nothing is built under a valid key, and lists any in-flight Jobs.
459
-
460
- State the current runtime truth: first-phase public builds execute registered Python Operators through `FeatureOperatorRunner`. Do not claim that Chronon compile/backfill or Chronon-native feature computation occurred unless the artifact contains and passes those explicit execution records.
461
-
462
- ## Report The Outcome
463
-
464
- Return a concise business-facing summary containing:
465
-
466
- ```text
467
- catalog and version
468
- new / unchanged assets by type
469
- planned versus resolved dependency versions and any explicitly retained old versions
470
- Operator package filename and SHA-256
471
- FeatureSet and ordered feature count
472
- dataset id, version, manifest hash, and Job id
473
- row and column counts
474
- rowset candidate / policy-applied / eligible / ineligible counts when endpoint_policy is declared
475
- validation status, warnings, and missing-data summary
476
- artifact location
477
- actual compute backend
478
- ```
479
-
480
- If the work stops before publication, distinguish generated files, locally validated files, dry-run validation, and remotely published assets.
@@ -1,4 +0,0 @@
1
- interface:
2
- display_name: "特征与实时取数管理"
3
- short_description: "管理版本化 Parameter、Operator、Feature、数据集与实时推理取数"
4
- default_prompt: "Use $feature-management to manage versioned feature assets, build datasets, or fetch one causal realtime inference row through the platform API."
@@ -1,23 +0,0 @@
1
- {
2
- "schema_version": "ml_data_platform.catalog/v1",
3
- "name": "example_business_feature_catalog",
4
- "version": "v1",
5
- "parameters": [
6
- "parameters/example_temperature.v1.json"
7
- ],
8
- "operators": [
9
- {
10
- "spec": "operators/example_temperature_features.v1.json",
11
- "package": "operator_package/dist/business_feature_operator_template-1.0.0-py3-none-any.whl"
12
- }
13
- ],
14
- "features": [
15
- "features/example_temperature_mean_5m.v1.json"
16
- ],
17
- "feature_sets": [
18
- "feature_sets/example_temperature_core.v1.json"
19
- ],
20
- "datasets": [
21
- "datasets/example_temperature_training.v1.json"
22
- ]
23
- }
@@ -1,40 +0,0 @@
1
- {
2
- "schema_version": "ml_data_platform.dataset_manifest/v1",
3
- "project": "replace_with_project",
4
- "dataset_id": "example_temperature_training",
5
- "dataset_version": "v1",
6
- "mode": "training",
7
- "read_policy": "snapshot",
8
- "time_range": {
9
- "start": "2026-07-01T00:00:00+08:00",
10
- "end": "2026-07-02T00:00:00+08:00",
11
- "grid": "10min"
12
- },
13
- "prediction": {
14
- "horizon": "0min"
15
- },
16
- "rowset": {
17
- "strategy": "fixed_grid",
18
- "grid": "10min"
19
- },
20
- "parameters": [],
21
- "parameter_missing_policies": [
22
- {
23
- "parameter": "example_temperature",
24
- "version": "v1",
25
- "project": "replace_with_project",
26
- "policy": "report_only"
27
- }
28
- ],
29
- "feature_set": {
30
- "name": "example_temperature_core",
31
- "version": "v1"
32
- },
33
- "preprocess": [],
34
- "output": {
35
- "format": "parquet",
36
- "include_stats": true,
37
- "include_lineage": true,
38
- "engine": "chronon"
39
- }
40
- }
@@ -1,14 +0,0 @@
1
- {
2
- "schema_version": "ml_data_platform.feature_set/v1",
3
- "project": "replace_with_project",
4
- "name": "example_temperature_core",
5
- "version": "v1",
6
- "features": [
7
- {
8
- "name": "example_temperature_mean_5m",
9
- "version": "v1"
10
- }
11
- ],
12
- "owner": "replace_with_business_owner",
13
- "description": "Ordered example temperature features."
14
- }
@@ -1,28 +0,0 @@
1
- {
2
- "schema_version": "ml_data_platform.feature/v1",
3
- "project": "replace_with_project",
4
- "name": "example_temperature_mean_5m",
5
- "version": "v1",
6
- "inputs": [
7
- {
8
- "parameter": "example_temperature",
9
- "version": "v1",
10
- "project": "replace_with_project"
11
- }
12
- ],
13
- "operator": "example_temperature_features",
14
- "operator_version": "v1",
15
- "config": {
16
- "window": "5min",
17
- "window_closed": "right",
18
- "cutoff_included": true,
19
- "post_cutoff_allowed": false,
20
- "duplicate_event_time": "last",
21
- "empty_window": "null"
22
- },
23
- "output_column": "example_temperature_mean_5m",
24
- "output_dtype": "float64",
25
- "offline_online_supported": false,
26
- "owner": "replace_with_business_owner",
27
- "description": "Mean example temperature in the causal interval (target-5min, target]."
28
- }
@@ -1,12 +0,0 @@
1
- [build-system]
2
- requires = ["hatchling"]
3
- build-backend = "hatchling.build"
4
-
5
- [project]
6
- name = "business-feature-operator-template"
7
- version = "1.0.0"
8
- requires-python = ">=3.10"
9
- dependencies = ["pandas>=2.3.3"]
10
-
11
- [tool.hatch.build.targets.wheel]
12
- packages = ["src/business_feature_operator_template"]
@@ -1,39 +0,0 @@
1
- """Example business Feature Operator. Replace names and formulas before use."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import Any
6
-
7
- import pandas as pd
8
-
9
-
10
- SUPPORTED_OUTPUTS = {"example_temperature_mean_5m"}
11
-
12
-
13
- def compute_features(context: Any) -> pd.DataFrame:
14
- requested = list(dict.fromkeys(context.requested_output_columns))
15
- unknown = sorted(set(requested) - SUPPORTED_OUTPUTS)
16
- if unknown:
17
- raise ValueError(f"unsupported output columns: {unknown}")
18
-
19
- input_keys = {item.parameter: item.key for item in context.inputs}
20
- parameter_key = input_keys.get("example_temperature")
21
- if parameter_key is None:
22
- raise ValueError("example_temperature input is required")
23
-
24
- frame = context.metric_frames[parameter_key]
25
- values = pd.to_numeric(
26
- frame.set_index("timestamp")["value"],
27
- errors="coerce",
28
- ).sort_index()
29
- if values.index.has_duplicates:
30
- values = values.groupby(level=0).last()
31
-
32
- window = pd.Timedelta(str(context.config["window"]))
33
- output: dict[str, object] = {"event_time": context.target_times}
34
- if "example_temperature_mean_5m" in requested:
35
- output["example_temperature_mean_5m"] = [
36
- values.loc[(values.index > target - window) & (values.index <= target)].mean()
37
- for target in context.target_times
38
- ]
39
- return pd.DataFrame(output)