Skip to content

MILAB-6810: migrate onto the structurer + add block kind - #3

Merged
AStaroverov merged 6 commits into
mainfrom
MILAB-6810_migrate-to-structurer
Sep 2, 2026
Merged

MILAB-6810: migrate onto the structurer + add block kind#3
AStaroverov merged 6 commits into
mainfrom
MILAB-6810_migrate-to-structurer

Conversation

@AStaroverov

@AStaroverov AStaroverov commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Migrates the block onto the structurer and takes the full SDK upgrade that the require-latest CI gate forces.

What changed

SDK upgrade + structure refresh (fd1da35) — the canonical upgrade-sdk flow: block-tools 2.12.9 → 2.14.3, tengo-builder 4.0.20 → 4.0.23, model 1.83.0, ui-vue 1.83.3. The refresh reported 8 structural changes (kind configs, plus managed package.json across block/model/kind/workflow/software). structure check is now a fixpoint.

Block kind (4f49236) — the structurer hard-fails a kind-less block (declares no kind — every block must have a sibling kind/ package), so this adds kind/.

The init-params contract is inputAnchor + species: the two fields .args() requires, and the only ones a user sets by hand. Left out deliberately:

  • datasetLabel — derived by the UI from the picked option's label, not user input.
  • tableState / distributionGraphState — view state.

init now consumes params (every field keeping its default fallback, since a block may init without a template) and .templateParams projects the same two fields back, so export and apply stay inverses.

SPECIES_OPTIONS moves into the kind and is re-exported from the model — the kind cannot import from the model, and duplicating the list would let the contract and the UI dropdown drift apart.

Notes

  • BlockParams.inputAnchor is declared string to match the model's BlockData, but the parser checks it with the SDK's isColumnUniversalId. Every value the picker can produce is a deriveColumnOptions id, so the stricter runtime check matches reachable states without pulling the UI's selectDataset into a retype.
  • kind/ is private and never npm-published; its content reaches consumers through the kinds/ registry tree. model.json records …generation-probability.kind@1.0.0.

Verification

  • pnpm build:dev-no-software12/12 green (model, ui, workflow, kind, block; type + lint + format checks included).
  • block-tools structure check — up to date, 0 changes.
  • Not run: workflow/integration tests against a live backend.

Greptile Summary

The PR upgrades the Platforma SDK and workspace structure, introduces the mandatory block-kind package, and adds a template initialization contract for dataset and species settings. It also refreshes package metadata and enables CI enforcement that changesets bump the published block package.

  • Block kind — the typed identity and initialization contract for a category of blocks; added as a private workspace package with runtime validation for inputAnchor and species.
  • Initialization parameters (BlockParams) — settings that templates can supply when creating a block; introduced with optional dataset-anchor and species fields.
  • Template parameters — the projection of live block state used for template export; added to return the same inputAnchor and species consumed during initialization.
  • Input anchor — the universal column identifier for the selected dataset; now accepted from initialization parameters and validated by isColumnUniversalId.
  • Species — the generation-probability model selection (human or mouse); its options move into the kind package and are re-exported by the model.
  • Block model — the durable state, workflow arguments, and derived outputs exposed to Platforma; now associates itself with the new kind and initializes configurable state from template parameters.
  • Structurer — block-tools automation that normalizes package structure and dependencies; the workspace and managed manifests are refreshed for its current conventions.
  • Changeset — release metadata describing package version changes; added for the block, model, workflow, and software packages.
  • Package-path bump gate — CI validation requiring the published block package to receive a changeset bump; enabled in the reusable build workflow.

Confidence Score: 5/5

The PR appears safe to merge because no concrete blocking or independently actionable non-blocking defect was established.

The kind, model initialization, template projection, package graph, and release-gate changes are internally aligned, and the investigated packaging and identifier-validation concerns lacked a demonstrated reachable failure.

Important Files Changed

Filename Overview
kind/src/index.ts Defines the new kind identity, species vocabulary, initialization-parameter type, and runtime validation.
kind/package.json Adds the private block-kind package and its build, check, export, and dependency configuration.
model/src/index.ts Associates the model with the kind, initializes state from template parameters, and adds the inverse template projection.
block/package.json Connects the kind package to the block’s workspace build graph while preserving the packaged component map.
.github/workflows/build.yaml Enables changeset enforcement for the published block package.
pnpm-workspace.yaml Registers the kind workspace and refreshes shared SDK and tooling catalog versions.
pnpm-lock.yaml Locks the new kind dependency graph and the coordinated SDK/tooling upgrades.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  T[Project template] -->|inputAnchor and species| K[Block kind parser]
  K -->|validated BlockParams| M[Block model initialization]
  M --> A[Workflow arguments]
  M -->|templateParams| T
  M --> P[Generated model manifest]
  P --> B[Packaged block]
  B --> R[Platforma registry and runtime]
Loading

Reviews (1): Last reviewed commit: "MILAB-6810: changeset" | Re-trigger Greptile

Context used (4)

Full SDK upgrade via the canonical upgrade-sdk flow (block-tools 2.14.3,
tengo-builder 4.0.23, model 1.83.0, ui-vue 1.83.3) plus the structure
refresh output. Scaffolds the kind/ package the structurer now requires --
its contract lands in the next commit.
BlockParams is the dataset pick plus the species -- the two fields .args()
requires, and the only ones a user sets by hand. datasetLabel is derived by
the UI from the picked option, and the table / distribution-chart state is
view state; neither is configuration a template carries.

init now consumes params (each field keeping its default fallback) and
.templateParams projects the same two fields back, so export and apply stay
inverses. SPECIES_OPTIONS moves into the kind and is re-exported from the
model, so the contract and the UI dropdown cannot name different sets.
…g via the model

SPECIES_OPTIONS lives in the kind; the model was re-exporting it purely so
MainPage.vue could reach it. The UI can depend on the kind package itself,
so the pass-through goes away and each consumer imports from the definition.

BlockData.species now names the kind's Species type directly rather than
deriving it from typeof SPECIES_OPTIONS.
A project template seeds inputAnchor alone -- datasetLabel is derived from
the picked option, so the kind's contract leaves it out and a seeded block
rendered its subtitle with the species but no dataset name. A watcher now
fills it once the options resolve, from the same lookup the picker uses.

Cosmetic only: unlike clonotype-convergence, args does not read the label,
so a seeded block was always runnable.
Five things, all found by re-reading docs/column-access-api.md and the
2026-05-20 column-access migration.

Exact matchers instead of bare strings. A bare string in a selector
normalises to a REGEX -- unanchored, with '.' as a wildcard -- and PGEN_NAME
was used as the include for primaryColumns and the exclude for the rest, so a
future column carrying it as a prefix would land in both. No collision today
(minlog10GenerationProbability does not match), so this is latent.

ColumnsCollection instead of AccessorColumnsProvider. Providers are plumbing;
pgenTable in the same file already used the collection.

Name filtering moved host-side in pgenGraphPf and pgenGraphPfCols. Both read
getSpec (and getData) for every column in the pframe and then dropped the
non-Pgen ones in JS. Now only the survivors pay a round trip.

isDataColumn guards both PColumn bridges. PColumn.id and
PColumnIdAndSpec.columnId are PObjectId slots, which only a bare leaf
carries -- true here by source, now true by construction.

inputOptions labels survivors only. deriveColumnOptions reads the spec of
every entry handed to it, so passing the unfiltered collection re-read the
columns the scorability check had just discarded.
@AStaroverov
AStaroverov merged commit 646ea72 into main Sep 2, 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