Files
whynot-design/adapters/lit/drift/_report.json
tegwick 552d8fe926 feat(adapter): Lit component scaffold + drift report (WHYNOT-WP-0002 T07)
Extend make adapt-lit beyond tokens: parse src/elements/*.js, compare each IR
component contract against its <wn-*> element, and emit per-component drift
reports + a machine roll-up (adapters/lit/drift/), with write-once stubs
(adapters/lit/stubs/) for genuinely new components. Never overwrites
hand-authored sources.

- Severity split: actionable drift (prop-missing, attribute-mismatch,
  variant-axis-missing, tag-mismatch) gates with exit 3; non-portable + prop-extra
  are informational (the IR carries React style/onClick; Lit is richer than the
  minimal designbook) and don't gate.
- Current state: 7 ok, 3 actionable drift for human triage — PipelineStrip
  (wn-pipeline-strip vs hand-authored wn-pipeline rename), PageHeader (actions is
  a slot, not a prop), Sidebar (IR 'current' axis absent on the element).
- _report.json reuses generatedAt/irRef when drift is unchanged (no git churn).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 09:03:22 +02:00

223 lines
6.0 KiB
JSON

{
"stack": "lit",
"generatedAt": "2026-06-30T07:01:40.219Z",
"irRef": "17f2ad9",
"components": [
{
"name": "Button",
"status": "ok",
"tag": "wn-button",
"issues": [
{
"kind": "non-portable",
"prop": "onClick",
"detail": "type=function; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
},
{
"kind": "non-portable",
"prop": "style",
"detail": "type=object; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "size",
"detail": "on <wn-button> (attribute 'size'), not in IR contract.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "iconEnd",
"detail": "on <wn-button> (attribute 'icon-end'), not in IR contract.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "type",
"detail": "on <wn-button> (attribute 'type'), not in IR contract.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "disabled",
"detail": "on <wn-button> (attribute 'disabled'), not in IR contract.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "href",
"detail": "on <wn-button> (attribute 'href'), not in IR contract.",
"severity": "info"
}
]
},
{
"name": "Eyebrow",
"status": "ok",
"tag": "wn-eyebrow",
"issues": [
{
"kind": "non-portable",
"prop": "style",
"detail": "type=object; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "strong",
"detail": "on <wn-eyebrow> (attribute 'strong'), not in IR contract.",
"severity": "info"
}
]
},
{
"name": "Icon",
"status": "ok",
"tag": "wn-icon",
"issues": [
{
"kind": "non-portable",
"prop": "style",
"detail": "type=object; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
}
]
},
{
"name": "PageHeader",
"status": "drift",
"tag": "wn-page-header",
"issues": [
{
"kind": "prop-missing",
"prop": "actions",
"detail": "in IR (attribute 'actions'), absent on <wn-page-header>",
"severity": "drift"
},
{
"kind": "prop-extra",
"prop": "hasActions",
"detail": "on <wn-page-header> (attribute 'hasactions'), not in IR contract.",
"severity": "info"
}
]
},
{
"name": "PipelineStrip",
"status": "drift",
"tag": "wn-pipeline-strip",
"issues": [
{
"kind": "tag-mismatch",
"expected": "wn-pipeline-strip",
"actual": "wn-pipeline",
"detail": "IR contract tag 'wn-pipeline-strip' has no element; 'wn-pipeline' looks like the hand-authored counterpart (rename — resolve in Claude Design or realign the element).",
"severity": "drift"
}
]
},
{
"name": "Sidebar",
"status": "drift",
"tag": "wn-sidebar",
"issues": [
{
"kind": "prop-missing",
"prop": "current",
"detail": "in IR (attribute 'current'), absent on <wn-sidebar>",
"severity": "drift"
},
{
"kind": "non-portable",
"prop": "onNav",
"detail": "type=function; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
},
{
"kind": "variant-axis-missing",
"prop": "current",
"detail": "IR variant axis 'current' (doc:) has no Lit property.",
"severity": "drift"
},
{
"kind": "prop-extra",
"prop": "activation",
"detail": "on <wn-sidebar> (attribute 'activation'), not in IR contract.",
"severity": "info"
}
]
},
{
"name": "StageDot",
"status": "ok",
"tag": "wn-stage-dot",
"issues": [
{
"kind": "non-portable",
"prop": "style",
"detail": "type=object; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
}
]
},
{
"name": "Stamp",
"status": "ok",
"tag": "wn-stamp",
"issues": [
{
"kind": "non-portable",
"prop": "style",
"detail": "type=object; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
}
]
},
{
"name": "Tag",
"status": "ok",
"tag": "wn-tag",
"issues": [
{
"kind": "non-portable",
"prop": "style",
"detail": "type=object; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
}
]
},
{
"name": "TopNav",
"status": "ok",
"tag": "wn-top-nav",
"issues": [
{
"kind": "non-portable",
"prop": "onNew",
"detail": "type=function; not attribute-mappable — handle explicitly, never drop.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "logoSrc",
"detail": "on <wn-top-nav> (attribute 'logo-src'), not in IR contract.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "brand",
"detail": "on <wn-top-nav> (attribute 'brand'), not in IR contract.",
"severity": "info"
},
{
"kind": "prop-extra",
"prop": "slug",
"detail": "on <wn-top-nav> (attribute 'slug'), not in IR contract.",
"severity": "info"
}
]
}
]
}