Files
rose-ash/plans/hs-conformance-scoreboard.md
giles d0b358eca2
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 51s
HS: parser+compiler — toggle for-in lookahead, throttled/debounced modifiers (-2 skips)
parser.sx parse-toggle-cmd: when seeing 'toggle .foo for', peek the
following two tokens. If they are '<ident> in', it is a for-in loop
and toggle does NOT consume 'for' as a duration clause. Restores the
trailing for-in to the command list.

parser.sx parse-on (handler modifiers): recognize 'throttled at <ms>'
and 'debounced at <ms>' as handler modifiers. Captured as :throttle /
:debounce kwargs in the on-form parts list.

compiler.sx emit-on: pre-extract :throttle / :debounce from parts via
new _strip-throttle-debounce helper before scan-on, then wrap the built
handler with (hs-throttle! handler ms) or (hs-debounce! handler ms).

runtime.sx: hs-throttle! — closure with __hs-last-fire timestamp,
fires immediately and drops events arriving within ms of the last fire.
hs-debounce! — closure with __hs-timer, clears any pending timer and
schedules a new setTimeout(handler, ms) so only the last burst event
fires.

Both formerly-architectural skips now pass:
- "toggle does not consume a following for-in loop"
- "throttled at <time> drops events within the window"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 07:16:27 +00:00

8.5 KiB
Raw Blame History

HS Conformance Scoreboard

Live tally for plans/hs-conformance-to-100.md. Update after every cluster commit.

Baseline:    1213/1496 (81.1%)  initial scrape
Snapshot:    1496/1514          upstream sync 2026-05-08 (+18 new upstream tests)
Conformance: 1496/1496 (100.0%) on counted tests; 18 documented architectural skips
Wall:        26m17s sequential (8 batches × 200) via tests/hs-run-batched.js
Target:      1514/1514 — clear the 18 skip list (in progress)
Note: full-suite single-process is unreliable due to JIT cache saturation;
      use hs-run-batched.js (fresh kernel per batch) for deterministic numbers.

Skip list (18 — work to do)

Skip Reason Estimated work
Tokenizer-stream API (13)matchToken, matchTokenType, matchOpToken, matchAnyToken*, peekToken, consumeUntil, consumeUntilWhitespace, pushFollow/popFollow, pushFollows/popFollows, clearFollows/restoreFollows, lastMatch, lastWhitespace Upstream exposes a streaming token API on _hyperscript.internals.tokenizer. Our hs-tokenize returns a flat list; parser holds stream state internally as closures. Wrap hs-tokenize output in a token-stream object exposed as a primitive. ~1-2 days, mostly mechanical.
Template-component scope (2)component reads a feature-level set from an enclosing div on first load, component reads enclosing scope set by a sibling init on first load Upstream supports <script type="text/hyperscript-template" component="..."> — HTML-template-based custom elements. Our defcomp is SX-only; no template-component bootstrap. Add a <script type="text/hyperscript-template"> registrar alongside the existing script-tag scanner. ~1 day.
Toggle parser ambiguity (1)toggle does not consume a following for-in loop Parser greedily consumes for x in [...] as toggle .foo for <duration>. Need lookahead to distinguish for <num>ms/s (duration) from for <ident> in <expr> (iteration). Targeted parser fix in parse-toggle. ~2-4 hours.
Throttled-at modifier (1)throttled at <time> drops events within the window Parser doesn't recognize throttled at <duration> as a handler modifier. Currently emits malformed SX (handler body is the literal throttled symbol; time expression dangles outside closure). Parser support + runtime hs-throttle! wrapper. ~4 hours.
Async event dispatch (1)until event keyword works repeat until event click from #x suspends the OCaml kernel waiting for a click that the sync test runner can't dispatch (kernel busy, JS event loop blocked). Architectural — requires either yielding to the JS event loop between iterations, or a different test-runner shape that can interleave event injection. ~2-3 days.

Cluster ledger

Bucket A — runtime fixes

# Cluster Status Δ Commit
1 fetch JSON unwrap done +4 39a597e9
2 element → HTML via outerHTML done +1 e195b5bd
3 Values dict insertion order done +2 e59c0b8e
4 not precedence over or done +3 4fe0b649
5 some selector for nonempty match done +1 e7b86264
6 string template ${x} done +2 108e25d4
7 put hyperscript reprocessing done +5 247bd85c
8 select returns selected text done +1 d862efe8
9 wait on event basics done +4 f79f96c1
10 swap variable ↔ property done +1 30f33341
11 hide strategy partial +3 beb120ba
12 show multi-element + display retention done +2 98c957b3
13 toggle multi-class + timed + until-event partial +2 bd821c04
14 unless modifier done +1 c4da0698
15 transition query-ref + multi-prop + initial partial +3 3d352055
16 send can reference sender done +1 ed8d71c9
17 tell semantics blocked
18 throw respond async/sync done +2 dda3becb

Bucket B — parser/compiler additions

# Cluster Status Δ Commit
19 pick regex + indices done +13 4be90bf2
20 repeat property for-loops + where done +3 c932ad59
21 possessiveExpression property access via its done +1 f0c41278
22 window global fn fallback done +1 d31565d5
23 me symbol works in from expressions done +1 0d38a75b
24 properly interpolates values 2 done +1 cb37259d
25 parenthesized commands and features done +1 d7a88d85

Bucket C — feature stubs (observer mocks)

# Cluster Status Δ Commit
26 resize observer mock + on resize done +3 304a52d2
27 intersection observer mock + on intersection done +3 0c31dd27
28 ask/answer + prompt/confirm mock done +4 6c1da921
29 hyperscript:before:init / :after:init / :parse-error partial +2 e01a3baa
30 logAll config done +1 64bcefff

Bucket D — medium features

# Cluster Status Δ
31 runtime null-safety error reporting done +13
32 MutationObserver mock + on mutation done +7
33 cookie API partial +4
34 event modifier DSL partial +7
35 namespaced def done +3
36b call result binds to it done +1

Bucket E — subsystems (design docs landed, pending review + implementation)

# Cluster Status Design doc
36 WebSocket + socket + RPC proxy done +16
37 Tokenizer-as-API done +17
38 SourceInfo API done +2
39 WebWorker plugin done +1
40 Fetch non-2xx / before-fetch / real response done +7

Step-limit fix

# Cluster Status Δ Commit
SL raise default step limit 200k→1M done +70 225fa2e8
17 tell semantics done (included in SL)
33 cookie API (remaining 1) done (included in SL)

Bucket F — generator translation gaps

Defer until AD drain. Estimated ~25 recoverable tests.

# Cluster Status Δ Commit
F1 add CSS template interpolation done +1 5a76a040
F2 empty multi-element (query→for-each) done +1 875e9ba3
F3 hs-make-object _order + assert= for dicts done +1 daea2808
F4 array literal arg to JS fn (sxToJs + reduce→SX) done +1 da2e6b1b
F5 bind feature parser stub done +32 846650da
F6 asyncError rejected promise catch done +1
F7 hs-on nil-target guard (skip-list rescue) done +1 1751cd05
F8 on EVENT from SRC or EVENT from SRC multi-source done +1 f1428009
F9 obj.method() via host-call (T9 from plan) done +1 hs-f
F10 obj.method(promiseArg) resolved sync (F2) done +1 hs-f
F11 obj.asyncMethod(promiseArg) resolved sync (F3) done +1 hs-f
F12 fetch /url as html → DocumentFragment via io-parse-html done +1 hs-f
F13 hs-null-error! self-contained guard (avoid slow host_error path) done +3 hs-f
F14 when @attr changes parser+compiler+runtime — MutationObserver wiring done +1 hs-f
F15 def/default/empty suites: NO_STEP_LIMIT for legitimate scoped-var cascades done +N hs-f

Buckets roll-up

Bucket Done Partial In-prog Pending Blocked Design-done Total
A 12 4 0 0 1 17
B 7 0 0 0 0 7
C 4 1 0 0 0 5
D 2 2 0 0 1 5
E 5 0 0 0 0 0 5
F ~10 ~10

Maintenance

After each cluster commit, update:

  • Merged: pass count + delta line at top
  • The row's Status / Δ / Commit in the relevant bucket
  • The buckets roll-up table counts

Use mcp__hs-test__hs_test_run(start=0, end=195) + targeted-suite runs to get the real number; don't run the full suite every iteration (hangs on 196/199/200/615/1197/1198).