Skip to content

Add the mandatory block kind and upgrade the SDK - #40

Merged
AStaroverov merged 6 commits into
mainfrom
feat/project-template-migration
Aug 20, 2026
Merged

Add the mandatory block kind and upgrade the SDK#40
AStaroverov merged 6 commits into
mainfrom
feat/project-template-migration

Conversation

@AStaroverov

@AStaroverov AStaroverov commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

What

Adds the now-mandatory kind to the Rarefaction block and takes it through the SDK upgrade that comes with it. Part of the batch bringing every block onto project templates.

The init-params contract

The kind carries the block's identity and its init-params contract — what a project template supplies to seed a new instance. Eight optional fields:

Group Fields
Input datasetRef (PlRef, guarded by isPlRef)
Analysis numPoints, numIterations, extrapolation
Resources mem, cpu
Labels datasetLabel, customBlockLabel

numPoints / numIterations are checked as strings because that is what the block stores — the UI binds them to text inputs, so a half-typed value is an ordinary state, and the model's args is what holds them to integers. A parser stricter than the states the editor can reach would make export and apply stop being inverses.

Left out: tableState and graphState — pure view state. A template carrying them would restore one user's scroll position and plot config onto another user's block.

init and templateParams name the same eight fields, so the round trip is lossless.

The drift guard

params.ts checks its CONTRACT table against BlockParams with a satisfies clause. Every contract field is optional, so a parser that simply forgot one would otherwise return a valid BlockParams and say nothing; with the guard, adding a field without a runtime check fails to compile.

Also in here

  • SDK upgrade — block-tools 2.12.7 → 2.14.3, model 1.80.2 → 1.82.0, ui-vue 1.80.4 → 1.82.1, tengo-builder 4.0.18 → 4.0.23, workflow-tengo 6.7.2 → 6.8.2, plus the surrounding toolchain. No majors.
  • Dropped pnpm.overrides — ten SDK packages had been pinned to local monorepo tarballs. @platforma-sdk/block-kind is published now, and those file: paths do not exist in CI.
  • --unstable kept on the facade's prepublishOnly. The structurer strips that flag on refresh, so it is re-added deliberately — structure check reports it as drift, which is expected here.

Verification

  • turbo run build12/12 green; pnpm install --frozen-lockfile clean.
  • block-tools structure check — fixpoint apart from the intended --unstable drift.
  • Round trip proven against the built kind/dist: a full eight-field params object comes back deep-equal, {} is accepted, a half-typed editor state is accepted, unknown keys are dropped rather than refused, and malformed envelopes (null, a number, an array) plus every per-field type error are rejected.
  • Drift guard proven to bite: deleting a CONTRACT entry fails the type-check with TS1360.
  • model/dist/model.json records kind: "@platforma-open/milaboratories.rarefaction.kind@1.0.0".

Not run: block tests (need a live backend) and the kind publish loop (needs registry credentials). Template export→apply is proven at the parser and by init/templateParams naming the same fields, not by a running project cycle.

Greptile Summary

The PR introduces the mandatory Rarefaction block kind and upgrades the Platforma SDK/toolchain, wiring template initialization and export through a shared eight-field contract.

  • Block kind: the package-level identity and initialization contract for Rarefaction; added as a new kind/ workspace package and connected to the model and facade.
  • Initialization parameters: template-supplied values used to seed a block; expanded to cover dataset wiring, analysis settings, resource limits, and labels, with runtime type guards.
  • Template parameters: the model projection used when exporting a block into a project template; added with the same eight fields as initialization to support round trips.
  • PlRef: a Platforma reference to another block’s output; datasetRef is now accepted through the kind contract and validated with isPlRef.
  • Resource limits: per-process memory and CPU settings; now accepted from templates, although the parser does not preserve the editor’s positive-value constraint.
  • View state: table and graph presentation state; deliberately excluded from the template contract.
  • SDK catalog: centrally pinned Platforma and Milaboratories dependencies; upgraded alongside Node-based CI from Node 20 to Node 22.
  • Unstable publication: publication to the block registry before stable promotion; explicitly enabled in the facade’s prepublishOnly command.

Confidence Score: 4/5

The PR should not merge until template-supplied CPU and memory values are constrained to valid positive resource limits.

The new template path accepts zero and negative resource values, bypasses the editor’s minimum constraint, and forwards those values unchanged into workflow execution resource requests.

Files Needing Attention: kind/src/params.ts

Important Files Changed

Filename Overview
kind/src/params.ts Adds field-by-field runtime validation for template initialization, but permits non-positive CPU and memory values that the editor disallows.
kind/src/types.ts Defines the eight optional initialization fields while intentionally excluding graph and table view state.
kind/src/index.ts Defines the package-derived block-kind identity and connects it to the initialization parser.
model/src/index.ts Connects the kind to the data model, initializes state from template parameters, and exports the corresponding template projection.
pnpm-workspace.yaml Registers the kind workspace and upgrades the shared SDK and build-tool catalog.
.github/workflows/build.yaml Moves CI to Node 22 and enables enforcement that the published block package receives a changeset bump.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  T[Project template] --> P[Kind parameter parser]
  P --> I[Model init]
  I --> S[Live block state]
  S --> A[Model args]
  A --> W[Workflow resource configuration]
  S --> E[templateParams export]
  E --> T2[Exported project template]
Loading

Fix all with Greploop Fix All in Claude Code

Prompt To Fix All With AI
### Issue 1
kind/src/params.ts:75-76
**Non-positive resource limits pass validation**

When a project template supplies zero or a negative integer for `mem` or `cpu`, the parser accepts it and the model forwards it unchanged into workflow resource configuration, causing invalid requests such as `-1GiB` to fail during scheduling instead of rejecting the template during initialization.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "chore: add changeset for the block kind" | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

`structure refresh` output plus the kind/ workspace member it needs to
discover: block-tools 2.12.7 -> 2.14.3, model 1.80.2 -> 1.82.0, ui-vue
1.80.4 -> 1.82.1, tengo-builder 4.0.18 -> 4.0.23, workflow-tengo 6.7.2 ->
6.8.2, plus ts-builder, ts-configs, package-builder, test and helpers.

Drops the pnpm.overrides block that pinned ten SDK packages to local
monorepo tarballs: @platforma-sdk/block-kind is published now, and those
file: paths do not exist in CI.

Keeps --unstable on the facade's prepublishOnly. The structurer strips
that flag on refresh, so it is re-added deliberately and will show up as
drift in `structure check`.
Eight optional fields: the dataset reference, the three analysis knobs,
the per-process resource limits, and the two labels. tableState and
graphState stay out — a template carrying them would restore one user's
scroll position and plot config onto another user's block.

The CONTRACT table is checked against BlockParams by a satisfies clause,
so a field added to the contract without a runtime check fails to
compile. Every field being optional is what makes that guard necessary:
a parser that simply forgot one would otherwise return a valid
BlockParams and say nothing.
The data model is built with the kind, so its BlockParams type flows into
init, and the model records which kind it implements. templateParams
projects the same eight fields back out, so export and apply are
inverses.
Comment thread kind/src/params.ts Outdated
Comment on lines +75 to +76
mem: check(isInteger, "an integer"),
cpu: check(isInteger, "an integer"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Non-positive resource limits pass validation

When a project template supplies zero or a negative integer for mem or cpu, the parser accepts it and the model forwards it unchanged into workflow resource configuration, causing invalid requests such as -1GiB to fail during scheduling instead of rejecting the template during initialization.

Prompt To Fix With AI
This is a comment left during a code review.
Path: kind/src/params.ts
Line: 75-76

Comment:
**Non-positive resource limits pass validation**

When a project template supplies zero or a negative integer for `mem` or `cpu`, the parser accepts it and the model forwards it unchanged into workflow resource configuration, causing invalid requests such as `-1GiB` to fail during scheduling instead of rejecting the template during initialization.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code

Drops the hand-written isInteger / isNumber / isFiniteNumber wrappers in
favour of isNumber and isArray from es-toolkit/compat, which is where the
narrowing versions live: the root entry ships neither.

Two checks get looser, both deliberately. A fractional value now passes
where isInteger refused it — whether 2.5 CPUs means anything is the
block's own args to settle, not the kind's, which checks the envelope.
And NaN passes, which JSON.parse cannot produce, so it is unreachable by
the only route params travel.

What stays local is what es-toolkit has no equivalent for: the Guard and
Check types, the check factory, and the oneOf / arrayOf / optional
combinators. All of it sits below the Internals divider.
Publishing goes to the normal channel. The flag was carried while the
batch was in flight; the structurer strips it on every refresh, so
keeping it also meant `structure check` reporting this one field as
drift forever.
@AStaroverov
AStaroverov merged commit a12ec7e into main Aug 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant