Skip to content

feat(spec): add the map visualization config block to ListViewSchema - #9370

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-9340-listview-map-config
Aug 17, 2026
Merged

feat(spec): add the map visualization config block to ListViewSchema#9370
os-steve merged 1 commit into
mainfrom
claude/issue-9340-listview-map-config

Conversation

@os-steve

Copy link
Copy Markdown
Collaborator

Fixes#9340

Cross-repo transfer of objectui#5001 (spec-side by that card's ruling): ListViewSchema is strict and declared seven per-visualization config blocks but no map block, so a type: 'map' list view could not declare its field mapping or camera at all. The showcase task map fell back to the renderer's titleField default name — an object with only title — so every marker title rendered undefined.

What landed

  • ListMapConfigSchema (packages/spec/src/ui/view.zod.ts) — the eighth visualization block, registered as map on ListViewSchema beside the seven siblings. Key set anchored in two measurements, both quoted in the schema's JSDoc:
    • objectui plugin-map's actual read surface: getMapConfig in ObjectMap.tsx validates schema.map against a local zod schema with exactly latitudeField / longitudeField / locationField / titleField / descriptionField / zoom / center, each with a live read in the renderer (coordinate extraction, marker title/description, camera init); the same seven keys are the documented surface in content/docs/plugins/plugin-map.mdx. No key without a live read was admitted.
    • Sibling-block precedent for shape and refusal behaviour: strictObject with surface name + VIEW_HISTORY, .describe() per key, edit-distance prescription on unknown keys.
  • Strict, not passthrough — gantt/tree passthrough exists because those renderers add knobs ahead of the spec; the map renderer's read set is itself closed (it validates schema.map and drops extras), so passthrough here would silently strip nothing-reads-this keys. A misspelling is now a loud parse error.
  • No defaults on zoom / center, deliberately — objectui#5000 ruled "declared camera wins, no declaration means fit to the queried records"; a spec-side default would read as a declared camera and defeat the fit. Consequently the alias is isomorphic and pinned (Iso851, count 837 to 838 with receipt) in type-alias-convention.pin.test.ts.
  • Naming: not MapConfigSchema — the automation map flow-node config (automation/builtin-node-config.zod.ts) already exports that name; same collision, same resolution as ListChartConfigSchema vs chart.zod.ts's ChartConfigSchema. check:dual-source-exports is why this matters.
  • Tests (view.test.ts): accept cases (full seven-key surface, the exact showcase shape, empty config with no defaults applied), strict refusal asserting prescription substance (surface name + offending key echoed + titleField suggestion + verbatim history sentence, both standalone and nested inside ListViewSchema), and value-level refusals (zoom outside 1-20, center arity/type).
  • Liveness ledger (liveness/view.json + README row): map recorded planned, deliberately not live — the component-level reader exists (ObjectMap.tsx reads schema.map) but objectui ListView.tsxcase 'map' forwards only schema.options?.map, never the view-level block, so authoring the key changes nothing at runtime until the pre-registered objectui consumer card lands the forwarding (measured against the objectui checkout current today). VIEW_BINDING_BLOCKS in functional-completeness.ts was deliberately NOT extended — it is Tier-A verify-then-enforce (timeline/tree are likewise excluded).
  • Showcase (examples/app-showcase/src/ui/views/task.view.ts): pure metadata addition demonstrating the block — map: { titleField: 'title', locationField: 'location' } on the map view, plus the now-stale "map needs a spec MapConfigSchema" comment corrected. allowedVisualizations untouched (switcher wiring is the objectui follow-up).
  • Generated artifacts regenerated via check:generated --fix: api-surface/ui.json, authorable-surface/ui.json, export-origins/ui.json, json-schema.manifest/ui.json, content/docs/references/**, strictness-ledger counts, liveness state-counts.
  • Changeset: @objectstack/spec minor (accepted-set expansion; not breaking, so no ADR-0087 marker required — check:adr-0087-registration green).

Verification (all at dd2cb8d1d)

  • pnpm --filter @objectstack/spec test — 408 files / 10880 tests passed (re-run post-commit at this head).
  • pnpm --filter @objectstack/spec typecheck, check:generated (all 13 current), check:liveness — green.
  • dispatch-gates re-derived from the actual diff; every named family run locally and green: cross-package-test-inputs, doc-authoring, doc-formula-expressions, docs-audit-scope, docs-redirects, empty-state, merge-driver, quick-reference-counts, role-word, spec-parsed-alias, strictness-ledger, type-source-resolution, variant-docs, dev-prereqs, affected-docs n/a via lint families, nul-bytes, adr-0087-registration, query-options-erasure, type-check-coverage, type-check-debt (workspace built), engine-double-contract, where-matcher.
  • Showcase: pnpm --filter @objectstack/example-showcase validate && typecheck — green (pre-existing unrelated warnings only).
  • Reverse verification (from the committed state): restoring origin/main's view.zod.ts turns exactly the 8 new tests red (missing export + map refused on ListViewSchema); restoring the branch file returns them green. Direction observed: red, as predicted.

Out of scope

The objectui consumer wiring (ListView forwarding view.map to plugin-map, switcher inclusion) is the pre-registered follow-up card the PM files on landing — objectui#5001 remains closed as transferred; #9340 remains the tracking card until merge.


Generated by Claude Code

…9340)
The eighth per-visualization block, isomorphic to the seven ruled siblings.
ListMapConfigSchema declares the map renderer's documented read surface
(latitudeField/longitudeField/locationField/titleField/descriptionField/
zoom/center), strict, no defaults (declared camera wins; no declaration =>
renderer fits the queried records). Showcase task map view now declares
titleField: 'title' + locationField: 'location'.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fs18A2DdXLVN2h8PaaFBcP
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 3 documentable anchor(s).

1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17.mdx(via ListViewSchema (symbol))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 7 changed file(s) yielded no anchor (packages/spec/api-surface/ui.json, packages/spec/authorable-surface/ui.json, packages/spec/export-origins/ui.json, …) — pages documenting those are invisible to this run

Coarse fallback — 113 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json origin/mainpackageMentionDocs.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-steve
os-steve marked this pull request as ready for review August 17, 2026 19:53
@os-steve
os-steve added this pull request to the merge queueAug 17, 2026
Merged via the queue into main with commit 90c5285Aug 17, 2026
27 of 30 checks passed
@os-steve
os-steve deleted the claude/issue-9340-listview-map-config branch August 17, 2026 20:14
os-steve pushed a commit that referenced this pull request Aug 18, 2026
…dvisory, loudly
The `Flag docs affected by code changes` job died four consecutive times on
PR #9370 (2026-08-17, 17:17Z-18:24Z) with a 503 from
`/repos/.../issues/9370/comments`. actions/github-script routes any throw from
the inline script to `main().catch(handleError)` -> `core.setFailed(...)`, so a
degraded GitHub API turned an advisory-only check red and cost four re-runs
that no local change could have fixed.
Delivery of the advisory comment now retries a bounded, narrow transient class
(5xx, 429, 403 carrying a secondary-rate-limit signature, and network-level
codes) and, once the retries are spent, degrades VISIBLY instead of failing:
a warning annotation plus a job summary that names the failed call, states that
the run's verdict is NOT on the pull request, warns that any advisory comment
shown there is from an earlier push, and reproduces the verdict it did compute.
The tolerance is scoped to delivery only. A malformed `affected.json`, a 422
over-long body, a plain 403 permission denial and any non-HTTP error still fail
the job — swallowing those would let "could not tell" render as "no drift",
which is the same defect wearing the opposite mask.
Fixes#9373
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/mteststooling

Projects

None yet

2 participants

@os-steve@claude