Skip to content

feat(react-inspector): schema annotation tooltips, container labels, and lineage#688

Merged
schickling merged 8 commits into
mainfrom
schickling/2026-05-25-react-inspector
May 25, 2026
Merged

feat(react-inspector): schema annotation tooltips, container labels, and lineage#688
schickling merged 8 commits into
mainfrom
schickling/2026-05-25-react-inspector

Conversation

@schickling-assistant
Copy link
Copy Markdown
Collaborator

@schickling-assistant schickling-assistant commented May 25, 2026

Closes #686. Closes #687.

Summary

Three related improvements to @overeng/react-inspector:

1. Rich schema annotation tooltips

Replaces the previous native title= attribute on schema-annotated tree nodes with a proper hover/focus tooltip that surfaces every useful Effect Schema annotation at once — description, examples, default, refinement-derived constraints (min/max/length/pattern/format/...), and possible values for Literal / Enums / Union-of-literal / TemplateLiteral ASTs.

Tooltip attaches to field names, root labels, and struct type badges in collapsed previews. Triggers are keyboard-focusable and wire aria-describedby to the tooltip for screen readers.

Example: hovering age on Schema.Number.pipe(Schema.int(), Schema.between(0, 150)).annotations({ identifier: 'Age', title: 'Age', description: 'Age in whole years', examples: [18, 42, 80], default: 0 }) shows:

Age                          refinement
Age in whole years
CONSTRAINTS  ≥ 0, ≤ 150
DEFAULT      0
EXAMPLES
  • 18
  • 42
  • 80

2. Schema-derived container labels (closes #686)

Arrays, records, tuples, Maps, Sets, and tagged unions now surface their schema-derived type instead of the runtime constructor name:

  • Schema.Array(Item)Array<Item>(N) (was Array(N))
  • Schema.Array(Item).annotations({ identifier: 'Pinned' })Pinned(N)
  • Schema.Record({ key: String, value: Money })Record<string, Money> (was Object)
  • Schema.Tuple(String, Number, Boolean)[string, number, boolean]
  • Schema.Map({ key, value })Map<K, V>(N) (+ ReadonlyMap, Set, ReadonlySet)
  • Schema.Union(EventA, EventB, EventC) with _tag discriminator + matching runtime _tag → narrows display to the matched variant (display name, tooltip, container label, nested-field resolution)

SchemaInfo gains optional containerLabel: string. getFieldSchema falls back to indexSignature.type for records. SchemaProvider gains an optional rootData prop; context exposes new getContextForPathWithValue(path, value) for the union-narrowing path. withSchemaSupport forwards data as rootData automatically.

3. Lineage annotations (closes #687)

New Lineage namespace describing the epistemic status of a field — where the value comes from, who owns it, how fresh it is, what it references.

Design: hybrid of the issue's options (A) + (B) — one fat tagged union for the core kinds, plus small composable companion annotations.

import { Lineage } from '@overeng/react-inspector'

const OrderTotals = Schema.Struct({
  subtotal: Schema.Number.pipe(Lineage.sourceOfTruth({ owner: 'orders' })),
  tax: Schema.Number.pipe(Lineage.sourceOfTruth()),
  total: Schema.Number.pipe(Lineage.derivedFrom(['subtotal', 'tax'], 'Pure', { pure: true })),
  cachedFxRate: Schema.Number.pipe(Lineage.cache('fxRate', { ttlMs: 60_000 })),
  customerId: Schema.String.pipe(
    Lineage.authority({ writers: ['orders-svc'], readers: ['*'] }),
    Lineage.freshness({ capturedAt: 'event-time', maxAgeMs: 5_000 }),
    Lineage.foreignKey('Customer', 'id'),
  ),
})

The schema-aware renderer surfaces:

  • A small superscript glyph next to annotated field names (ƒ derived, projection, cache, mirror, external, computed). SourceOfTruth is the implicit default — no glyph.
  • A dedicated LINEAGE / AUTHORITY / FRESHNESS / REF block in the schema tooltip.
  • data-lineage-target attributes on Derived.from field paths, ready for a future jump-to-source UI.

All annotation shapes are themselves Effect Schemas (self-describing per #687 acceptance). Extractors fail-soft via Schema.decodeUnknownOption. 9 round-trip vitest tests.

Bug fixes bundled in

  • getFieldSchema no longer eagerly unwraps refinement / transformation wrappers — user-supplied description / examples / default on .pipe(int(), between(...)).annotations(...) chains now reach the tooltip.
  • getConstraintsFromJSONSchema recurses before writing fragments so outer refinements win on duplicate keys (between(0, 100).pipe(between(10, 50)) now correctly reports 10..50, not 0..100).
  • WeakSet cycle guard in getConstraintsFromJSONSchema against self-referential Suspend.
  • SchemaTooltip closes on scroll/resize and Escape per WCAG.
  • Two pre-existing no-shadow warnings in @overeng/notion-md (blocking --deny-warnings CI for any branch).

New exports

  • SchemaTooltip, SchemaTooltipProps
  • SchemaInfo, SchemaConstraint, LineageBundle
  • getSchemaInfo(schema), getConstraintsFromJSONSchema(ast), getPossibleValuesFromAST(ast)
  • Lineage namespace (annotation symbols, schemas, extractors, pipe constructors, getLineageDisplay)

Storybook

  • SchemaTooltipFull / SchemaTooltipKeyboardA11y / SchemaTooltipTruncatedPossibleValues / SchemaTooltipMixedAnnotated
  • ContainerLabels — arrays, named arrays, records, tuples
  • MapAndSetContainerLabels
  • RuntimeTaggedUnionNarrowing
  • LineageAnnotations — every lineage tag + companion-only example

Filtering

Effect's built-in primitive descriptions ("a string", "a number", etc.) are filtered out of hasContent, so primitive fields without user annotations do not get a tooltip affordance.

Implementation notes

  • Tooltip is hand-rolled with React state instead of React Aria. The interaction we need (hover + focus + aria-describedby + Escape-to-close) is small enough that the dep isn't worth it, and RAC's TooltipTrigger requires its child to consume FocusableContext with an interactive ARIA role — which a tree-item field-name span isn't.
  • Tooltip uses position: fixed + pointer-events: none so it can't sit on top of adjacent tree-row triggers and block hover. Important for dense (~14px) tree rows.
  • Runtime union narrowing runs on every path segment, not just the leaf, so deeply nested fields under a tagged union resolve through the matched variant.

Test plan

  • tsc --noEmit clean
  • oxlint --import-plugin --deny-warnings (via oxlint-with-plugins Nix wrapper) — 0 warnings, 0 errors across packages/ scripts/ context/
  • oxfmt --check clean
  • vitest run — 39 tests passing
  • Manual verification with playwright-cli against each new story (screenshots in tmp/schema-tooltip-screenshots/)
  • Verified existing stories still render correctly (ComplexOrderExample now shows Array<Order Item>(2), ApiResponseWithDescriptions, ExpandedVsCollapsedPreview, etc.)
  • CI green: lint, devenv-perf, typecheck, test (linux+macos), test-integration-notion, nix-check, nix-fod-check, pnpm-regression, deploy-storybooks

🤖 Generated with Claude Code

Posted on behalf of @schickling
field value
agent_name 🍂 cl2-ash
agent_session_id 6343ad62-30a6-4407-8f9e-3675206d78bf
agent_tool Claude Code
agent_tool_version 2.1.139
agent_runtime Claude Code 2.1.139
agent_model claude-opus-4-7
worktree effect-utils/schickling/2026-05-25-react-inspector
machine mbp2025
tooling_profile dotfiles@4e6515b

Replaces the previous native `title=` attribute with a proper hover/focus
tooltip that surfaces every useful Effect Schema annotation at once:

- description, documentation
- examples (formatted via `pretty` when present)
- default
- constraints derived from `JSONSchemaAnnotationId` set by refinements
  (`nonEmptyString`, `int`, `between`, `pattern`, `format`, …)
- possible values for `Literal`, `Enums`, `Union`-of-literal, and
  `TemplateLiteral` ASTs (capped at 12 with `… +N more`)

Tooltips attach to field names, root labels, and struct type badges.
Triggers are keyboard-focusable and wire `aria-describedby` to the
tooltip for screen-reader users.

Bug fix: `getFieldSchema` no longer eagerly unwraps refinement /
transformation wrappers, so user-supplied annotations on a
`.pipe(...).annotations(...)` chain reach the tooltip. Downstream
traversal still works because each lookup re-applies `unwrapAstForDisplay`
at its entry point.

Effect's built-in primitive descriptions like "a string" / "a number"
are filtered out of `hasContent`, so primitive fields without user
annotations do not get a tooltip affordance.

New exports: `SchemaTooltip`, `SchemaInfo`, `SchemaConstraint`,
`getSchemaInfo`, `getConstraintsFromJSONSchema`,
`getPossibleValuesFromAST`.

Storybook: new `SchemaTooltipFull` (exercises every annotation kind),
`SchemaTooltipKeyboardA11y`, `SchemaTooltipTruncatedPossibleValues`,
`SchemaTooltipMixedAnnotated` stories.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@schickling schickling marked this pull request as ready for review May 25, 2026 16:38
@github-actions github-actions Bot requested a review from schickling May 25, 2026 16:38
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 511ae87b7a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/@overeng/react-inspector/src/schema/effectSchema.tsx Outdated
Comment thread packages/@overeng/react-inspector/src/schema/SchemaAwareObjectPreview.tsx Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

Storybook Previews

Package Latest URL Last Deploy (Europe/Berlin)
effect-react https://effect-react-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
react-inspector https://react-inspector-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
effect-schema-form-aria https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
genie https://genie-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
notion-cli https://notion-cli-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
notion-react https://notion-react-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
notion-md https://notion-md-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
tui-react https://tui-react-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
megarepo https://megarepo-pr-688--overeng-utils.netlify.app 2026-05-26 00:30 CEST
Per-Commit Deploy History

Commit 8203d0c · 2026-05-26 00:30 CEST

Package URL
effect-react https://6a14cd67d4281a3264aa18a2--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a14cd6717600f4069555840--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a14cd6825694a5e564bf203--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a14cd69572cfa502b8139cd--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a14cd680d4e89266a605cd9--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a14cd672cfcdb590cc1598f--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a14cd69890e238a48c19bb2--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a14cd6af6e33d2fddfa93f9--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a14cd6b67b4865a3afb3061--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

Commit 0da4fb3 · 2026-05-25 22:57 CEST

Package URL
effect-react https://6a14b783d4281afa14aa18b8--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a14b783a26fdffad2bbcb94--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a14b7849bd7ddb374a53e91--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a14b784f6c248edf1680e21--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a14b784896ae02ebe360dfe--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a14b78379379818b5f55466--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a14b78439f53b040d1f9d3d--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a14b7862cfcdb2128c15a28--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a14b7873ce7252f6f02622d--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

Commit 9daa5e1 · 2026-05-25 22:42 CEST

Package URL
effect-react https://6a14b4199b12b6fa1a829cdb--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a14b4197937980f64f55598--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a14b41922605f10082f2ee3--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a14b41aea73c0ea726c7efe--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a14b41a1be7ddfa35ecb357--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a14b4199db1b201105f0fbf--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a14b41bf6c248e353680f56--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a14b41c25694a1be44bf2d8--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a14b41d39f53bfad11f9d43--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

Commit cdd581d · 2026-05-25 22:05 CEST

Package URL
effect-react https://6a14ab4c793798f7abf553d3--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a14ab4ceaa35ce4fbe3b4c5--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a14ab4d2d470035997340a7--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a14ab4d1fc19b368ae2d70e--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a14ab4e572cfaf7538138fe--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a14ab4d9d991b36c884423b--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a14ab4e0271c40e507492b1--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a14ab4e007813f7b5bfab02--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a14ab50846294d61e109b27--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

Commit 3500923 · 2026-05-25 21:51 CEST

Package URL
effect-react https://6a14a80e779fbbeb8dc75d72--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a14a80d0d4e89c6bf605d1f--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a14a80e2d47002b6a733f4a--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a14a80f17600fde5a555846--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a14a80ff1dc50e8bc96c306--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a14a80db7ee37e0835773ca--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a14a80fb9a9102a9ff468e9--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a14a810890e232ac9c19a43--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a14a81235301fcab37e78b4--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

Commit 75ade97 · 2026-05-25 21:47 CEST

Package URL
effect-react https://6a14a741890e23290bc19ac0--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a14a74039f53bd7951f9eb8--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a14a74135301fc9307e7824--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a14a74108f9706d2d958560--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a14a7422cfcdbf5abc15ac6--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a14a74124a34e8162056503--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a14a742ef366fe252f7d507--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a14a743793798eb1bf5553d--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a14a744ad367b2b55793cb5--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

Commit 973b3aa · 2026-05-25 18:46 CEST

Package URL
effect-react https://6a147cad9db1b2644f5f0fd3--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a147cad94510674416114e0--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a147cae7027ab5993254caa--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a147caf3ce7258b08026156--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a147caf7027ab596a254c90--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a147cae3ce7258cb40260fc--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a147cb02b0a5d6f6955af5a--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a147cb09bd7dd171ba53d5f--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a147cb29451067336611508--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

Commit 511ae87 · 2026-05-25 18:41 CEST

Package URL
effect-react https://6a147ba52cfcdb796dc15a81--overeng-utils.netlify.app
Alias: https://effect-react-pr-688--overeng-utils.netlify.app
react-inspector https://6a147ba539f53b5a371f9d9c--overeng-utils.netlify.app
Alias: https://react-inspector-pr-688--overeng-utils.netlify.app
effect-schema-form-aria https://6a147ba69bd7dd1368a53d9d--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-688--overeng-utils.netlify.app
genie https://6a147ba69db1b2617a5f101e--overeng-utils.netlify.app
Alias: https://genie-pr-688--overeng-utils.netlify.app
notion-cli https://6a147ba6b56130577752d0ba--overeng-utils.netlify.app
Alias: https://notion-cli-pr-688--overeng-utils.netlify.app
notion-react https://6a147ba6eaa35c5e91e3b419--overeng-utils.netlify.app
Alias: https://notion-react-pr-688--overeng-utils.netlify.app
notion-md https://6a147ba7cc7f337e4e966716--overeng-utils.netlify.app
Alias: https://notion-md-pr-688--overeng-utils.netlify.app
tui-react https://6a147ba8ef366f6544f7d661--overeng-utils.netlify.app
Alias: https://tui-react-pr-688--overeng-utils.netlify.app
megarepo https://6a147ba808f970f727958421--overeng-utils.netlify.app
Alias: https://megarepo-pr-688--overeng-utils.netlify.app

schickling-assistant and others added 4 commits May 25, 2026 18:42
…N Schema collection

Two review fixes:

- `SchemaTooltip`: close on scroll and resize (capture-phase scroll
  listener so nested scrollable containers also trigger). Coords were
  captured once at open time and would otherwise drift away from the
  trigger element as the page scrolled.
- `getConstraintsFromJSONSchema`: guard against self-referential
  Suspend chains with a WeakSet. The try/catch around `ast.f()` does
  not catch identity-cycle recursion (it would StackOverflow without
  throwing).

Also: fix stale doc comment in `SchemaTooltip` that referenced a
"transform-anchored wrapper" that doesn't exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- `getConstraintsFromJSONSchema`: recurse before writing JSON Schema
  fragments so that outer refinements win on duplicate keys. Previous
  recurse-after-write order let inner refinements clobber tighter outer
  bounds (e.g. `between(0, 100).pipe(between(10, 50))` reported `0..100`
  instead of `10..50`).
- `SchemaAwareObjectPreview`: keep the "Object " badge as a tooltip
  trigger when a plain-object root has tooltip content but no
  `title`/`identifier`. Otherwise the description was unreachable at
  depth 0 because the field-name trigger doesn't exist for root nodes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trivial formatting nit — oxfmt prefers a leading `;` on the standalone
`<SchemaTooltip>` JSX example to make ASI-safe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…cords, tuples (#686)

Surface the schema's element/value/positional types in the type-badge
slot instead of falling back to the runtime constructor name:

- `Schema.Array(Item)` → `Array<Item>(N)` (was `Array(N)`)
- `Schema.Array(Item).annotations({ identifier: 'Pinned' })` → `Pinned(N)`
- `Schema.Record({ key: String, value: Money })` →
  `Record<string, Money>` (was `Object`)
- `Schema.Tuple(String, Number, Boolean)` → `[string, number, boolean](N)`

Element labels follow the same precedence as everywhere else:
`title` ?? `identifier` ?? type-kind. Anonymous structs/unions return
`undefined` and the renderer falls through to the previous behavior.

`getFieldSchema` now falls back to the first `indexSignature.type` when
no `propertySignature` matches, so per-field schema resolution works
inside records (tooltips, pretty formatting, nested navigation).

`SchemaInfo` gains an optional `containerLabel: string` field.

New `ContainerLabels` storybook story exercises all four cases.

Out of scope here (tracked separately under #686): `Map`/`Set`
containers, runtime tagged-union narrowing to a specific variant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
schickling-assistant and others added 2 commits May 25, 2026 22:39
…ations (#686, #687)

Wraps up the remaining work on issue #686 and adds the full lineage
annotation namespace from issue #687.

## #686 leftovers

- **Map/Set container labels**: `Schema.Map({key, value})` renders as
  `Map<K, V>(N)`, `Schema.Set(T)` as `Set<T>(N)`, plus the `Readonly*`
  variants. Detected via the `effect/annotation/TypeConstructor`
  annotation on `Declaration` ASTs (a stable internal Effect signal).
- **Runtime tagged-union narrowing**: when a field's declared schema is
  `Schema.Union(A, B, C)` of `_tag`-discriminated variants and the
  runtime value carries a matching `_tag`, the inspector narrows the
  display (name, tooltip, container label, nested-field resolution) to
  the matched variant. Narrowing happens on every path segment, not just
  the leaf, so deeply nested fields under a tagged union resolve through
  the matched variant. `SchemaProvider` gains an optional `rootData`
  prop; context exposes new `getContextForPathWithValue(path, value)`.
  `withSchemaSupport` / `withSchemaContext` forward `data` as `rootData`
  automatically, so HOC consumers get narrowing for free.

## #687 lineage annotations

New module `src/schema/lineage.ts` defining a hybrid namespace:

- **Fat tagged union** `Lineage`: `SourceOfTruth | Derived | Projection
  | Cache | Mirror | External | Computed` — answers the *epistemic*
  question "where does this field's value come from".
- **Companion annotations** (composable, orthogonal): `Authority`
  (writers/readers), `Freshness` (capturedAt + maxAgeMs),
  `ForeignKey` (target schema + field).
- All shapes are themselves Effect Schemas (self-describing per #687
  acceptance criteria), enabling decode-and-validate at the consumer.
- Ergonomic pipe-style constructors: `Schema.X.pipe(
  Lineage.derivedFrom(['a', 'b'], 'Pure', { pure: true }))`,
  `Lineage.cache('rate', { ttlMs: 60_000 })`, `Lineage.authority(...)`,
  etc. Bare-string `from` refs are coerced to `Field` shape.
- Extractors (`Lineage.getLineage(schema)` etc.) are fail-soft — corrupt
  annotation values return `undefined` rather than crashing the
  renderer.
- Round-trip tested in `src/schema/lineage.test.ts` (9 tests).

### Renderer wiring

- `SchemaInfo.lineage?: LineageBundle` bundles the lineage display +
  companion annotations.
- `SchemaTooltip` gains a `LINEAGE` section (kind badge + summary +
  optional details) plus `AUTHORITY` / `FRESHNESS` / `REF` rows.
- A small superscript glyph (`ƒ`, `≈`, `☷`, `↻`, `↗`, `⊙`) sits next to
  annotated field names. `SourceOfTruth` is the implicit default and
  intentionally has no badge to avoid clutter.
- `Derived.from` field paths in the tooltip carry
  `data-lineage-target="$.path"` for future jump-to-source wiring.

## Stories

- `MapAndSetContainerLabels` — `Schema.MapFromSelf`, `Schema.SetFromSelf`,
  `Schema.ReadonlyMapFromSelf` with real `Map`/`Set` values.
- `RuntimeTaggedUnionNarrowing` — `Schema.Union(EventCreated,
  EventUpdated, EventDeleted)` with two sample audit entries.
- `LineageAnnotations` — `OrderTotals` exercising every Lineage tag plus
  a companion-only example.

## Lints / CI

Fixed two pre-existing `no-shadow` warnings in `@overeng/notion-md`
(`opts` in `workspace.ts:visit`, `pageId` in `sync.e2e.test.ts:
readSyncStateFile`). CI runs `oxlint --deny-warnings`, so those were
blocking the lint job for any branch — unrelated to react-inspector
but needed for green CI on this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI runs oxlint through the @overeng/oxc-config JS plugin wrapper, which
adds the `overeng/explicit-boolean-compare` rule (requires `=== true`,
`=== false`, `!== null` instead of implicit boolean coercion). The base
`oxlint` binary on $PATH doesn't load the plugin, so these only surface
in CI.

Affected: SchemaContext.tsx, SchemaTooltip.tsx, SchemaAwareObjectPreview.tsx,
SchemaAwareNodeRenderer.tsx, effectSchema.tsx, lineage.ts. Pure mechanical
change — no behavior diffs.

Verified locally with the built oxlint-with-plugins wrapper:
0 warnings, 0 errors across packages/ scripts/ context/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
github-actions Bot added a commit that referenced this pull request May 25, 2026
github-actions Bot added a commit that referenced this pull request May 25, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

CI Measurements

partial - advisory gate - readiness partial (17/26 enabled observations gateable) - commit 8203d0c - protocol devenv-perf-warm-median-v2

No regressions. Comparable movement is below the semantic impact threshold; neutral rows are collapsed below.

Measurement change vs baseline chart

SVG source

nix / closures / packages

What changed? Group Probe Baseline -> current Raw change Impact Confidence
unchanged nix / closures / packages Nix sources closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Nix sources closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Nix sources closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Node / pnpm closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Node / pnpm closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Node / pnpm closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Rust closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Rust closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
unchanged nix / closures / packages Rust closure size 0 B -> 0 B +0 B / n/a n/a unknown, baseline n=7, current n=1
Unchanged / 0-impact measurements (17)

These rows had compatible baseline data, but their semantic impact rounded to 0.00x because the movement was below the configured budget, below the noise floor, or inside the robust noise band.

devenv / devenv cli

Group Probe Baseline -> current Raw change Impact Gate Evidence Why hidden
devenv / devenv cli devenv processes --help 0.023 s -> 0.022 s -0.001 s / -4.3% 0.00x yes paired n=9, 25-75% delta -0.001 s..0.001 s Too small to matter
devenv / devenv cli devenv tasks list 0.053 s -> 0.054 s +0.001 s / 1.9% 0.00x yes paired n=9, 25-75% delta -0.001 s..0.001 s Too small to matter

devenv / devenv shell

Group Probe Baseline -> current Raw change Impact Gate Evidence Why hidden
devenv / devenv shell Warm shell eval 6.19 s -> 6.133 s -0.057 s / -0.9% 0.00x yes paired n=5, 25-75% delta -0.086 s..0.026 s Too small to matter

devenv / genie

Group Probe Baseline -> current Raw change Impact Gate Evidence Why hidden
devenv / genie Genie check direct 9 s -> 9.026 s +0.026 s / 0.3% 0.00x yes paired n=5, 25-75% delta 0.008 s..0.033 s Too small to matter
devenv / genie Genie run task 1.449 s -> 1.427 s -0.022 s / -1.5% 0.00x yes paired n=5, 25-75% delta -0.024 s..0.02 s Too small to matter

devenv / quality gates

Group Probe Baseline -> current Raw change Impact Gate Evidence Why hidden
devenv / quality gates Forced check:quick 9.185 s -> 9.567 s +0.382 s / 4.2% 0.00x yes paired n=3, 25-75% delta -0.206 s..0.382 s Too small to matter
devenv / quality gates Warm cached check:quick 3.427 s -> 3.459 s +0.032 s / 0.9% 0.00x yes paired n=5, 25-75% delta -0.241 s..0.126 s Too small to matter

devenv / workspace setup

Group Probe Baseline -> current Raw change Impact Gate Evidence Why hidden
devenv / workspace setup pnpm install task 0.716 s -> 0.707 s -0.009 s / -1.3% 0.00x yes paired n=5, 25-75% delta -0.015 s..-0.007 s Too small to matter

nix / closures / packages

Group Probe Baseline -> current Raw change Impact Gate Evidence Why hidden
nix / closures / packages Total closure path count 80 count -> 80 count +0 count / 0% 0.00x yes noise_floor, baseline n=7, current n=1 Too small to matter
nix / closures / packages Total closure path count 5 count -> 5 count +0 count / 0% 0.00x yes noise_floor, baseline n=7, current n=1 Too small to matter
nix / closures / packages Total closure path count 8 count -> 8 count +0 count / 0% 0.00x yes noise_floor, baseline n=7, current n=1 Too small to matter
nix / closures / packages Total closure size 508.3 MiB -> 508.3 MiB +0 B / 0% 0.00x yes noise_floor, baseline n=7, current n=1 Too small to matter
nix / closures / packages Total closure size 141.9 MiB -> 141.9 MiB +0 B / 0% 0.00x yes noise_floor, baseline n=7, current n=1 Too small to matter
nix / closures / packages Total closure size 153.9 MiB -> 153.9 MiB +0 B / 0% 0.00x yes noise_floor, baseline n=7, current n=1 Too small to matter
nix / closures / packages Total serialized NAR size 508.3 MiB -> 508.3 MiB +0 B / 0% 0.00x yes noise_floor, baseline n=6, current n=1 Too small to matter
nix / closures / packages Total serialized NAR size 141.9 MiB -> 141.9 MiB +0 B / 0% 0.00x yes noise_floor, baseline n=6, current n=1 Too small to matter
nix / closures / packages Total serialized NAR size 153.9 MiB -> 153.9 MiB +0 B / 0% 0.00x yes noise_floor, baseline n=6, current n=1 Too small to matter
Diagnostic / ungated measurements (7)

source / effect-utils

Group Probe Current Baseline Impact Gate Reason Evidence
source / effect-utils Genie runtime lines 18874 lines 18806 lines diagnostic disabled Diagnostic only diagnostic, baseline n=8, current n=62
source / effect-utils Genie CI workflow helpers lines 6765 lines 6759.5 lines diagnostic disabled Diagnostic only diagnostic, baseline n=8, current n=7
source / effect-utils Genie runtime files 62 count 61.5 count diagnostic disabled Diagnostic only diagnostic, baseline n=8, current n=62
source / effect-utils Genie CI workflow helpers files 7 count 7 count diagnostic disabled Diagnostic only diagnostic, baseline n=8, current n=7
source / effect-utils Nix workspace tools files 13 count 13 count diagnostic disabled Diagnostic only diagnostic, baseline n=8, current n=13
source / effect-utils Nix workspace tools lines 3237 lines 3237 lines diagnostic disabled Diagnostic only diagnostic, baseline n=8, current n=13

devenv / devenv shell

Group Probe Current Baseline Impact Gate Reason Evidence
devenv / devenv shell Shell eval with OTEL trace 77.815 s n/a n/a missing_baseline No baseline yet missing_baseline, baseline n=0, current n=1
All measurements
Status Gate Target Observation Dimensions Baseline Current Delta Ratio Impact
pass disabled effect-utils repository Genie runtime lines scope=genie_runtime 18806 lines 18874 lines +68 lines 0.4% diagnostic
pass disabled effect-utils repository Genie CI workflow helpers lines scope=genie_ci_workflow 6759.5 lines 6765 lines +5.5 lines 0.1% diagnostic
pass disabled effect-utils repository Genie runtime files scope=genie_runtime 61.5 count 62 count +0.5 count 0.8% diagnostic
pass yes Dev shell Forced check:quick aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=3
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=3
phase=warm
probe=task_check_quick_forced
probeLabel=Forced check:quick
sampleCount=6
status=0
taskCacheMode=refresh
warmupCount=0
workload=forced-task-cache
9.185 s 9.567 s +0.382 s 4.2% 0.00x
pass yes Dev shell Warm shell eval aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=5
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=5
phase=warm
probe=shell_eval_warm
probeLabel=Warm shell eval
sampleCount=11
status=0
warmupCount=1
6.19 s 6.133 s -0.057 s -0.9% 0.00x
pass yes Dev shell Warm cached check:quick aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=5
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=5
phase=warm
probe=task_check_quick_warm
probeLabel=Warm cached check:quick
sampleCount=11
status=0
taskCacheMode=warm
warmupCount=1
workload=cached-no-op
3.427 s 3.459 s +0.032 s 0.9% 0.00x
pass yes Dev shell Genie check direct aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=5
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=5
phase=warm
probe=genie_check_direct
probeLabel=Genie check direct
sampleCount=11
status=0
warmupCount=1
9 s 9.026 s +0.026 s 0.3% 0.00x
pass yes Dev shell Genie run task aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=5
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=5
phase=warm
probe=task_genie_run
probeLabel=Genie run task
sampleCount=11
status=0
warmupCount=1
1.449 s 1.427 s -0.022 s -1.5% 0.00x
pass yes Dev shell pnpm install task aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=5
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=5
phase=warm
probe=task_pnpm_install
probeLabel=pnpm install task
sampleCount=11
status=0
warmupCount=1
0.716 s 0.707 s -0.009 s -1.3% 0.00x
pass yes Dev shell devenv processes --help aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=9
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=9
phase=warm
probe=processes_help
probeLabel=devenv processes --help
sampleCount=19
status=0
warmupCount=1
0.023 s 0.022 s -0.001 s -4.3% 0.00x
pass yes Dev shell devenv tasks list aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=9
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=9
phase=warm
probe=tasks_list
probeLabel=devenv tasks list
sampleCount=19
status=0
warmupCount=1
0.053 s 0.054 s +0.001 s 1.9% 0.00x
pass disabled effect-utils repository Genie CI workflow helpers files scope=genie_ci_workflow 7 count 7 count +0 count 0% diagnostic
unknown missing_baseline Genie package Nix sources closure size bucket=nix-sources 0 B 0 B +0 B n/a n/a
unknown missing_baseline Megarepo package Nix sources closure size bucket=nix-sources 0 B 0 B +0 B n/a n/a
unknown missing_baseline oxlint npm package Nix sources closure size bucket=nix-sources 0 B 0 B +0 B n/a n/a
pass disabled effect-utils repository Nix workspace tools files scope=nix_workspace_tools 13 count 13 count +0 count 0% diagnostic
pass disabled effect-utils repository Nix workspace tools lines scope=nix_workspace_tools 3237 lines 3237 lines +0 lines 0% diagnostic
unknown missing_baseline Genie package Node / pnpm closure size bucket=node 0 B 0 B +0 B n/a n/a
unknown missing_baseline Megarepo package Node / pnpm closure size bucket=node 0 B 0 B +0 B n/a n/a
unknown missing_baseline oxlint npm package Node / pnpm closure size bucket=node 0 B 0 B +0 B n/a n/a
unknown missing_baseline Genie package Rust closure size bucket=rust 0 B 0 B +0 B n/a n/a
unknown missing_baseline Megarepo package Rust closure size bucket=rust 0 B 0 B +0 B n/a n/a
unknown missing_baseline oxlint npm package Rust closure size bucket=rust 0 B 0 B +0 B n/a n/a
pass yes Genie package Total closure path count bucket=total 80 count 80 count +0 count 0% 0.00x
pass yes Megarepo package Total closure path count bucket=total 5 count 5 count +0 count 0% 0.00x
pass yes oxlint npm package Total closure path count bucket=total 8 count 8 count +0 count 0% 0.00x
pass yes Genie package Total closure size bucket=total 508.3 MiB 508.3 MiB +0 B 0% 0.00x
pass yes Megarepo package Total closure size bucket=total 141.9 MiB 141.9 MiB +0 B 0% 0.00x
pass yes oxlint npm package Total closure size bucket=total 153.9 MiB 153.9 MiB +0 B 0% 0.00x
pass yes Genie package Total serialized NAR size bucket=total
sizeKind=nar
508.3 MiB 508.3 MiB +0 B 0% 0.00x
pass yes Megarepo package Total serialized NAR size bucket=total
sizeKind=nar
141.9 MiB 141.9 MiB +0 B 0% 0.00x
pass yes oxlint npm package Total serialized NAR size bucket=total
sizeKind=nar
153.9 MiB 153.9 MiB +0 B 0% 0.00x
missing_baseline missing_baseline Dev shell Shell eval with OTEL trace aggregation=median
devenvRev=2cf62a010000b70f15c78a72761fad7c9e6fb47a
measuredSampleCount=1
measurementProtocol=devenv-perf-warm-median-v2
otelServiceName=devenv-perf-ci
pairedOrderProtocol=balanced-seeded-alternating-v1
pairedOrderSeed=26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d
pairedSampleCount=1
phase=warm
probe=shell_eval_traced
probeLabel=Shell eval with OTEL trace
sampleCount=2
status=0
warmupCount=0
n/a 77.815 s n/a n/a n/a
Previous runs
Commit Status Gate Top changes
0da4fb3 partial advisory Too small to matter Dev shell Forced check:quick +0.022 s / 0.2%
Too small to matter Dev shell Genie run task -0.014 s / -1%
Too small to matter Dev shell pnpm install task -0.014 s / -2.2%
Source-of-truth JSON
{
  "schemaVersion": 1,
  "title": "CI Measurements",
  "status": "partial",
  "gate": "advisory",
  "readiness": "partial (17/26 enabled observations gateable)",
  "commit": {
    "shortSha": "8203d0c",
    "sha": "8203d0cc06f450862c06644854def221dcbc2c80"
  },
  "run": {
    "id": "26422219238",
    "attempt": "1",
    "url": "https://github.com/overengineeringstudio/effect-utils/actions/runs/26422219238"
  },
  "baseline": null,
  "protocol": "devenv-perf-warm-median-v2",
  "chart": {
    "meaning": "semantic-impact",
    "zeroImpactMeaning": "no actionable PR impact after budgets, noise floor, and robust evidence checks",
    "svg": "https://raw.githubusercontent.com/overengineeringstudio/effect-utils/ci-measurement-assets/ci-measurements/pr-688/8203d0cc06f450862c06644854def221dcbc2c80/run-26422219238-attempt-1/ci-measurements.svg",
    "lightPng": "https://raw.githubusercontent.com/overengineeringstudio/effect-utils/ci-measurement-assets/ci-measurements/pr-688/8203d0cc06f450862c06644854def221dcbc2c80/run-26422219238-attempt-1/ci-measurements.png",
    "darkPng": "https://raw.githubusercontent.com/overengineeringstudio/effect-utils/ci-measurement-assets/ci-measurements/pr-688/8203d0cc06f450862c06644854def221dcbc2c80/run-26422219238-attempt-1/ci-measurements-dark.png"
  },
  "measurements": [
    {
      "id": "source.lines",
      "label": "Genie runtime lines",
      "group": "source / effect-utils",
      "path": [
        "source",
        "effect-utils",
        "packages",
        "genie",
        "source / genie"
      ],
      "groupPath": [
        "source",
        "effect-utils"
      ],
      "status": "pass",
      "direction": "regressed",
      "gateable": false,
      "gateReason": "disabled",
      "confidence": "diagnostic",
      "comparisonMode": "budget",
      "unit": "lines",
      "baseline": 18806,
      "current": 18874,
      "delta": 68,
      "ratio": 1.003615867276401,
      "semanticImpactScore": null,
      "semanticImpactKind": "diagnostic",
      "baselineSources": 8,
      "currentSamples": 62,
      "pairedSamples": 0,
      "evidenceDeltaLower": -1812.6000000000001,
      "evidenceDeltaUpper": 1948.6000000000001,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "scope": "genie_runtime"
      }
    },
    {
      "id": "source.lines",
      "label": "Genie CI workflow helpers lines",
      "group": "source / effect-utils",
      "path": [
        "source",
        "effect-utils",
        "genie",
        "ci-workflow",
        "source / ci"
      ],
      "groupPath": [
        "source",
        "effect-utils"
      ],
      "status": "pass",
      "direction": "regressed",
      "gateable": false,
      "gateReason": "disabled",
      "confidence": "diagnostic",
      "comparisonMode": "budget",
      "unit": "lines",
      "baseline": 6759.5,
      "current": 6765,
      "delta": 5.5,
      "ratio": 1.000813669650122,
      "semanticImpactScore": null,
      "semanticImpactKind": "diagnostic",
      "baselineSources": 8,
      "currentSamples": 7,
      "pairedSamples": 0,
      "evidenceDeltaLower": -670.45,
      "evidenceDeltaUpper": 681.45,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "scope": "genie_ci_workflow"
      }
    },
    {
      "id": "source.files",
      "label": "Genie runtime files",
      "group": "source / effect-utils",
      "path": [
        "source",
        "effect-utils",
        "packages",
        "genie",
        "source / genie"
      ],
      "groupPath": [
        "source",
        "effect-utils"
      ],
      "status": "pass",
      "direction": "regressed",
      "gateable": false,
      "gateReason": "disabled",
      "confidence": "diagnostic",
      "comparisonMode": "budget",
      "unit": "count",
      "baseline": 61.5,
      "current": 62,
      "delta": 0.5,
      "ratio": 1.008130081300813,
      "semanticImpactScore": null,
      "semanticImpactKind": "diagnostic",
      "baselineSources": 8,
      "currentSamples": 62,
      "pairedSamples": 0,
      "evidenceDeltaLower": -5.65,
      "evidenceDeltaUpper": 6.65,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "scope": "genie_runtime"
      }
    },
    {
      "id": "task_check_quick_forced",
      "label": "Forced check:quick",
      "group": "devenv / quality gates",
      "path": [
        "devenv",
        "quality gates",
        "check:quick"
      ],
      "groupPath": [
        "devenv",
        "quality gates"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 9.185,
      "current": 9.567,
      "delta": 0.3819999999999997,
      "ratio": 1.0415895481763744,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 3,
      "currentSamples": 3,
      "pairedSamples": 3,
      "evidenceDeltaLower": -0.206,
      "evidenceDeltaUpper": 0.382,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "workload": "forced-task-cache",
        "taskCacheMode": "refresh",
        "probe": "task_check_quick_forced",
        "probeLabel": "Forced check:quick",
        "status": 0,
        "sampleCount": 6,
        "warmupCount": 0,
        "measuredSampleCount": 3,
        "pairedSampleCount": 3,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "shell_eval_warm",
      "label": "Warm shell eval",
      "group": "devenv / devenv shell",
      "path": [
        "devenv",
        "devenv shell"
      ],
      "groupPath": [
        "devenv",
        "devenv shell"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 6.19,
      "current": 6.133,
      "delta": -0.057000000000000384,
      "ratio": 0.9907915993537963,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 5,
      "currentSamples": 5,
      "pairedSamples": 5,
      "evidenceDeltaLower": -0.086,
      "evidenceDeltaUpper": 0.026,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "probe": "shell_eval_warm",
        "probeLabel": "Warm shell eval",
        "status": 0,
        "sampleCount": 11,
        "warmupCount": 1,
        "measuredSampleCount": 5,
        "pairedSampleCount": 5,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "task_check_quick_warm",
      "label": "Warm cached check:quick",
      "group": "devenv / quality gates",
      "path": [
        "devenv",
        "quality gates",
        "check:quick"
      ],
      "groupPath": [
        "devenv",
        "quality gates"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 3.427,
      "current": 3.459,
      "delta": 0.03200000000000003,
      "ratio": 1.0093376130726583,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 5,
      "currentSamples": 5,
      "pairedSamples": 5,
      "evidenceDeltaLower": -0.241,
      "evidenceDeltaUpper": 0.126,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "workload": "cached-no-op",
        "taskCacheMode": "warm",
        "probe": "task_check_quick_warm",
        "probeLabel": "Warm cached check:quick",
        "status": 0,
        "sampleCount": 11,
        "warmupCount": 1,
        "measuredSampleCount": 5,
        "pairedSampleCount": 5,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "genie_check_direct",
      "label": "Genie check direct",
      "group": "devenv / genie",
      "path": [
        "devenv",
        "genie"
      ],
      "groupPath": [
        "devenv",
        "genie"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 9,
      "current": 9.026,
      "delta": 0.0259999999999998,
      "ratio": 1.002888888888889,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 5,
      "currentSamples": 5,
      "pairedSamples": 5,
      "evidenceDeltaLower": 0.008,
      "evidenceDeltaUpper": 0.033,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "probe": "genie_check_direct",
        "probeLabel": "Genie check direct",
        "status": 0,
        "sampleCount": 11,
        "warmupCount": 1,
        "measuredSampleCount": 5,
        "pairedSampleCount": 5,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "task_genie_run",
      "label": "Genie run task",
      "group": "devenv / genie",
      "path": [
        "devenv",
        "genie"
      ],
      "groupPath": [
        "devenv",
        "genie"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 1.449,
      "current": 1.427,
      "delta": -0.02200000000000002,
      "ratio": 0.9848171152518979,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 5,
      "currentSamples": 5,
      "pairedSamples": 5,
      "evidenceDeltaLower": -0.024,
      "evidenceDeltaUpper": 0.02,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "probe": "task_genie_run",
        "probeLabel": "Genie run task",
        "status": 0,
        "sampleCount": 11,
        "warmupCount": 1,
        "measuredSampleCount": 5,
        "pairedSampleCount": 5,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "task_pnpm_install",
      "label": "pnpm install task",
      "group": "devenv / workspace setup",
      "path": [
        "devenv",
        "workspace setup"
      ],
      "groupPath": [
        "devenv",
        "workspace setup"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 0.716,
      "current": 0.707,
      "delta": -0.009000000000000008,
      "ratio": 0.9874301675977654,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 5,
      "currentSamples": 5,
      "pairedSamples": 5,
      "evidenceDeltaLower": -0.015,
      "evidenceDeltaUpper": -0.007,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "probe": "task_pnpm_install",
        "probeLabel": "pnpm install task",
        "status": 0,
        "sampleCount": 11,
        "warmupCount": 1,
        "measuredSampleCount": 5,
        "pairedSampleCount": 5,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "processes_help",
      "label": "devenv processes --help",
      "group": "devenv / devenv cli",
      "path": [
        "devenv",
        "devenv cli"
      ],
      "groupPath": [
        "devenv",
        "devenv cli"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 0.023,
      "current": 0.022,
      "delta": -0.0010000000000000009,
      "ratio": 0.9565217391304347,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 9,
      "currentSamples": 9,
      "pairedSamples": 9,
      "evidenceDeltaLower": -0.001,
      "evidenceDeltaUpper": 0.001,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "probe": "processes_help",
        "probeLabel": "devenv processes --help",
        "status": 0,
        "sampleCount": 19,
        "warmupCount": 1,
        "measuredSampleCount": 9,
        "pairedSampleCount": 9,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "tasks_list",
      "label": "devenv tasks list",
      "group": "devenv / devenv cli",
      "path": [
        "devenv",
        "devenv cli"
      ],
      "groupPath": [
        "devenv",
        "devenv cli"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "paired",
      "unit": "seconds",
      "baseline": 0.053,
      "current": 0.054,
      "delta": 0.0010000000000000009,
      "ratio": 1.0188679245283019,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 9,
      "currentSamples": 9,
      "pairedSamples": 9,
      "evidenceDeltaLower": -0.001,
      "evidenceDeltaUpper": 0.001,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "probe": "tasks_list",
        "probeLabel": "devenv tasks list",
        "status": 0,
        "sampleCount": 19,
        "warmupCount": 1,
        "measuredSampleCount": 9,
        "pairedSampleCount": 9,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    },
    {
      "id": "source.files",
      "label": "Genie CI workflow helpers files",
      "group": "source / effect-utils",
      "path": [
        "source",
        "effect-utils",
        "genie",
        "ci-workflow",
        "source / ci"
      ],
      "groupPath": [
        "source",
        "effect-utils"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": false,
      "gateReason": "disabled",
      "confidence": "diagnostic",
      "comparisonMode": "budget",
      "unit": "count",
      "baseline": 7,
      "current": 7,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": null,
      "semanticImpactKind": "diagnostic",
      "baselineSources": 8,
      "currentSamples": 7,
      "pairedSamples": 0,
      "evidenceDeltaLower": -1,
      "evidenceDeltaUpper": 1,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "scope": "genie_ci_workflow"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Nix sources closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "genie",
        "buckets",
        "nix-sources",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "nix-sources"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Nix sources closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "megarepo",
        "buckets",
        "nix-sources",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "nix-sources"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Nix sources closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "oxlint-npm",
        "buckets",
        "nix-sources",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "nix-sources"
      }
    },
    {
      "id": "source.files",
      "label": "Nix workspace tools files",
      "group": "source / effect-utils",
      "path": [
        "source",
        "effect-utils",
        "nix",
        "workspace-tools",
        "source / nix"
      ],
      "groupPath": [
        "source",
        "effect-utils"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": false,
      "gateReason": "disabled",
      "confidence": "diagnostic",
      "comparisonMode": "budget",
      "unit": "count",
      "baseline": 13,
      "current": 13,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": null,
      "semanticImpactKind": "diagnostic",
      "baselineSources": 8,
      "currentSamples": 13,
      "pairedSamples": 0,
      "evidenceDeltaLower": -1.3,
      "evidenceDeltaUpper": 1.3,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "scope": "nix_workspace_tools"
      }
    },
    {
      "id": "source.lines",
      "label": "Nix workspace tools lines",
      "group": "source / effect-utils",
      "path": [
        "source",
        "effect-utils",
        "nix",
        "workspace-tools",
        "source / nix"
      ],
      "groupPath": [
        "source",
        "effect-utils"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": false,
      "gateReason": "disabled",
      "confidence": "diagnostic",
      "comparisonMode": "budget",
      "unit": "lines",
      "baseline": 3237,
      "current": 3237,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": null,
      "semanticImpactKind": "diagnostic",
      "baselineSources": 8,
      "currentSamples": 13,
      "pairedSamples": 0,
      "evidenceDeltaLower": -323.70000000000005,
      "evidenceDeltaUpper": 323.70000000000005,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "scope": "nix_workspace_tools"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Node / pnpm closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "genie",
        "buckets",
        "node",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "node"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Node / pnpm closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "megarepo",
        "buckets",
        "node",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "node"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Node / pnpm closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "oxlint-npm",
        "buckets",
        "node",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "node"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Rust closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "genie",
        "buckets",
        "rust",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "rust"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Rust closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "megarepo",
        "buckets",
        "rust",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "rust"
      }
    },
    {
      "id": "nix.closure.bucket.nar_size",
      "label": "Rust closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "oxlint-npm",
        "buckets",
        "rust",
        "nix closure buckets"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "unknown",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "unknown",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 0,
      "current": 0,
      "delta": 0,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": "unknown",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "rust"
      }
    },
    {
      "id": "nix.closure.path_count",
      "label": "Total closure path count",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "genie",
        "total",
        "path-count",
        "nix closure"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "budget",
      "unit": "count",
      "baseline": 80,
      "current": 80,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10,
      "evidenceDeltaUpper": 10,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total"
      }
    },
    {
      "id": "nix.closure.path_count",
      "label": "Total closure path count",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "megarepo",
        "total",
        "path-count",
        "nix closure"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "budget",
      "unit": "count",
      "baseline": 5,
      "current": 5,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10,
      "evidenceDeltaUpper": 10,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total"
      }
    },
    {
      "id": "nix.closure.path_count",
      "label": "Total closure path count",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "oxlint-npm",
        "total",
        "path-count",
        "nix closure"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "budget",
      "unit": "count",
      "baseline": 8,
      "current": 8,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10,
      "evidenceDeltaUpper": 10,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total"
      }
    },
    {
      "id": "nix.closure.nar_size",
      "label": "Total closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "genie",
        "total",
        "closure-size",
        "nix closure"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 533018624,
      "current": 533018624,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10660372.48,
      "evidenceDeltaUpper": 10660372.48,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total"
      }
    },
    {
      "id": "nix.closure.nar_size",
      "label": "Total closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "megarepo",
        "total",
        "closure-size",
        "nix closure"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 148820792,
      "current": 148820792,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total"
      }
    },
    {
      "id": "nix.closure.nar_size",
      "label": "Total closure size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "oxlint-npm",
        "total",
        "closure-size",
        "nix closure"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "budget",
      "unit": "bytes",
      "baseline": 161363816,
      "current": 161363816,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 7,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -10485760,
      "evidenceDeltaUpper": 10485760,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total"
      }
    },
    {
      "id": "nix.closure.serialized_nar_size",
      "label": "Total serialized NAR size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "genie",
        "total",
        "serialized-nar-size",
        "nix closure diagnostics"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "diagnostic",
      "unit": "bytes",
      "baseline": 533018624,
      "current": 533018624,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 6,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -53301862.400000006,
      "evidenceDeltaUpper": 53301862.400000006,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total",
        "sizeKind": "nar"
      }
    },
    {
      "id": "nix.closure.serialized_nar_size",
      "label": "Total serialized NAR size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "megarepo",
        "total",
        "serialized-nar-size",
        "nix closure diagnostics"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "diagnostic",
      "unit": "bytes",
      "baseline": 148820792,
      "current": 148820792,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 6,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -14882079.200000001,
      "evidenceDeltaUpper": 14882079.200000001,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total",
        "sizeKind": "nar"
      }
    },
    {
      "id": "nix.closure.serialized_nar_size",
      "label": "Total serialized NAR size",
      "group": "nix / closures / packages",
      "path": [
        "nix",
        "closures",
        "packages",
        "oxlint-npm",
        "total",
        "serialized-nar-size",
        "nix closure diagnostics"
      ],
      "groupPath": [
        "nix",
        "closures",
        "packages"
      ],
      "status": "pass",
      "direction": "unchanged",
      "gateable": true,
      "gateReason": "eligible",
      "confidence": "noise_floor",
      "comparisonMode": "diagnostic",
      "unit": "bytes",
      "baseline": 161363816,
      "current": 161363816,
      "delta": 0,
      "ratio": 1,
      "semanticImpactScore": 0,
      "semanticImpactKind": "neutral",
      "baselineSources": 6,
      "currentSamples": 1,
      "pairedSamples": 0,
      "evidenceDeltaLower": -16136381.600000001,
      "evidenceDeltaUpper": 16136381.600000001,
      "pairedEvidenceQuantile": 0.25,
      "dimensions": {
        "bucket": "total",
        "sizeKind": "nar"
      }
    },
    {
      "id": "shell_eval_traced",
      "label": "Shell eval with OTEL trace",
      "group": "devenv / devenv shell",
      "path": [
        "devenv",
        "devenv shell"
      ],
      "groupPath": [
        "devenv",
        "devenv shell"
      ],
      "status": "missing_baseline",
      "direction": "unknown",
      "gateable": false,
      "gateReason": "missing_baseline",
      "confidence": "missing_baseline",
      "comparisonMode": "historical",
      "unit": "seconds",
      "baseline": null,
      "current": 77.815,
      "delta": null,
      "ratio": null,
      "semanticImpactScore": null,
      "semanticImpactKind": null,
      "baselineSources": 0,
      "currentSamples": 1,
      "pairedSamples": null,
      "evidenceDeltaLower": null,
      "evidenceDeltaUpper": null,
      "pairedEvidenceQuantile": null,
      "dimensions": {
        "probe": "shell_eval_traced",
        "probeLabel": "Shell eval with OTEL trace",
        "status": 0,
        "sampleCount": 2,
        "warmupCount": 0,
        "measuredSampleCount": 1,
        "pairedSampleCount": 1,
        "pairedOrderProtocol": "balanced-seeded-alternating-v1",
        "pairedOrderSeed": "26422219238-1-80e9a6fe1a84c338f6ac49ca3617743a6db8997d",
        "measurementProtocol": "devenv-perf-warm-median-v2",
        "aggregation": "median",
        "phase": "warm",
        "devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
        "otelServiceName": "devenv-perf-ci"
      }
    }
  ]
}

github-actions Bot added a commit that referenced this pull request May 25, 2026
@schickling
Copy link
Copy Markdown
Collaborator

@codex

@schickling-assistant schickling-assistant changed the title feat(react-inspector): rich schema annotation tooltips feat(react-inspector): schema annotation tooltips, container labels, and lineage May 25, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0da4fb36c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/@overeng/react-inspector/src/schema/SchemaTooltip.tsx Outdated
…trigger

Codex P1 review on PR #688: `pointer-events: none` made the tooltip
unhoverable — combined with `onMouseLeave` close, long content was
unreadable, especially for magnification users.

The earlier `pointer-events: none` was over-correction for an adjacent-
row-blocking issue from the previous review round. Better fix: position
the tooltip to the right of the trigger (not below), so it lives outside
the tree's left column entirely. Sibling row triggers below the active
row are no longer covered, which lets the tooltip stay pointer-
interactive without blocking neighbor hover.

Placement: right-of-trigger → left-of-trigger (if right overflows) →
below-trigger clamped to viewport (last resort). Tooltip body now has
`pointer-events: auto`, `onMouseEnter` cancels the close timer, and
`onMouseLeave` re-arms it — standard hover-bridge behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@schickling schickling enabled auto-merge (squash) May 25, 2026 22:28
@schickling-assistant schickling-assistant added the mq:enrolled PR is enrolled in Hypermerge · Set: manual (mirrors GH auto-merge) label May 25, 2026
@schickling schickling merged commit 3fe965f into main May 25, 2026
17 checks passed
@schickling schickling deleted the schickling/2026-05-25-react-inspector branch May 25, 2026 22:37
github-actions Bot added a commit that referenced this pull request May 25, 2026
github-actions Bot added a commit that referenced this pull request May 25, 2026
github-actions Bot added a commit that referenced this pull request May 25, 2026
schickling-assistant added a commit that referenced this pull request May 26, 2026
…ackage

The `Lineage` annotation namespace was added to `@overeng/react-inspector`
in #688, but its definitions only depend on `effect` — the inspector merely
reads the annotations to render badges/tooltips. Pull the vocabulary into a
new `@overeng/schema-lineage` package so non-React consumers can annotate
schemas with epistemic lineage and share a single source of truth for the
schema, symbols, helpers, and display formatting.

- New package `@overeng/schema-lineage` exposes the Lineage namespace
  (`Lineage`, `LineageRef`, `DerivationKind`, `Authority`, `Freshness`,
  `Reference`, annotation symbols, `get*` readers, `getLineageDisplay`,
  and the `sourceOfTruth` / `derivedFrom` / `projection` / `cache` /
  `mirror` / `external` / `computed` / `authority` / `freshness` /
  `foreignKey` constructors).
- `react-inspector` adds `@overeng/schema-lineage` as a workspace dep and
  re-exports it as `Lineage` from `./schema/mod.tsx` and `./index.tsx`,
  preserving the public API surface from #688.
- Tightened `getLineageDisplay` to satisfy `exactOptionalPropertyTypes` in
  the new package's stricter tsconfig (no behavior change).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
schickling-assistant added a commit that referenced this pull request May 27, 2026
Move the `Lineage` annotation namespace (added in #688) out of
`@overeng/react-inspector` and into `@overeng/utils`, exposed through the
package's existing main isomorphic entry. Non-React consumers can now
annotate schemas with epistemic lineage without pulling in the inspector,
while sharing a single source of truth for the schema, symbols, helpers,
and display formatting.

Exposed via the existing `.` export (same pattern as `InMemoryBacking`)
rather than a separate `./lineage` subpath, since every other isomorphic
module already lives on the main entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
schickling-assistant added a commit that referenced this pull request May 27, 2026
Move the `Lineage` annotation namespace (added in #688) out of
`@overeng/react-inspector` and into `@overeng/utils`, exposed through the
package's existing main isomorphic entry. Non-React consumers can now
annotate schemas with epistemic lineage without pulling in the inspector,
while sharing a single source of truth for the schema, symbols, helpers,
and display formatting.

Exposed via the existing `.` export (same pattern as `InMemoryBacking`)
rather than a separate `./lineage` subpath, since every other isomorphic
module already lives on the main entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
schickling-assistant added a commit that referenced this pull request May 27, 2026
Move the `Lineage` annotation namespace (added in #688) out of
`@overeng/react-inspector` and into `@overeng/utils`, exposed through the
package's existing main isomorphic entry. Non-React consumers can now
annotate schemas with epistemic lineage without pulling in the inspector,
while sharing a single source of truth for the schema, symbols, helpers,
and display formatting.

Exposed via the existing `.` export (same pattern as `InMemoryBacking`)
rather than a separate `./lineage` subpath, since every other isomorphic
module already lives on the main entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
schickling-assistant added a commit that referenced this pull request May 27, 2026
Move the `Lineage` annotation namespace (added in #688) out of
`@overeng/react-inspector` and into `@overeng/utils`, exposed through the
package's existing main isomorphic entry. Non-React consumers can now
annotate schemas with epistemic lineage without pulling in the inspector,
while sharing a single source of truth for the schema, symbols, helpers,
and display formatting.

Exposed via the existing `.` export (same pattern as `InMemoryBacking`)
rather than a separate `./lineage` subpath, since every other isomorphic
module already lives on the main entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
schickling pushed a commit that referenced this pull request May 27, 2026
…ry (#695)

Move the `Lineage` annotation namespace (added in #688) out of
`@overeng/react-inspector` and into `@overeng/utils`, exposed through the
package's existing main isomorphic entry. Non-React consumers can now
annotate schemas with epistemic lineage without pulling in the inspector,
while sharing a single source of truth for the schema, symbols, helpers,
and display formatting.

Exposed via the existing `.` export (same pattern as `InMemoryBacking`)
rather than a separate `./lineage` subpath, since every other isomorphic
module already lives on the main entry.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mq:enrolled PR is enrolled in Hypermerge · Set: manual (mirrors GH auto-merge)

Projects

None yet

2 participants