Skip to content

Releases: ssheleg/super-ux

v0.56.0 — super-ux

Choose a tag to compare

@github-actions github-actions released this 10 Sep 01:03
c5b2528

Sherlock external-v3, 41 findings across this member, each one a commit carrying
its own executable regression under test/audit_regressions/. The ones worth
naming here:

  • Scenarios carry three axes, not one word. evidence_kind,
    decision_status and validation_status are separate: approval moves the
    decision, and only a dated interview or observation moves validation. A founder
    cannot promote a wished-for persona to observed by approving it.
  • Competitor funnels are observed exposure, never a proven base. The reference
    admitted a well-funded loss-maker looks profitable and then called common
    patterns proven; it now says what it can see. Frequency is computed with a
    denominator, duplicates collapsed — two funnels of one owner are ONE
    observation — and adoption is decided by a local experiment.
  • /ux-audit preconditions are per scope. A standalone blog with a brand pack
    and no scenarios runs the copy audit instead of being routed into writing
    scenarios it has no use for. Evidence is typed by claim: file:line for this
    codebase, URL + timestamp + capture for anything outside it.
  • BP-212 no longer calls local payment testing impossible. Three environments:
    a local sandbox tests the whole payment→webhook→entitlement→success path with
    the provider's own forwarding, and a public HTTPS endpoint is what PRODUCTION
    delivery needs.

Two documents now share the ground one filename used to: interactive-flow-prototypes.md
is the machine-checkable graph contract (IFP-01 … IFP-06), and
clickable-flow-prototypes.md is the operator-facing practice that arrived with the
context-ready handoff. prototyping.md owns the decision to reach for either.

ux-audit and ux-flows were split back under the house working limit —
audit-depth.md and prototyping.md — after the audit's own doctrine grew them
past it. CI now MEASURES that budget with a real tokenizer instead of estimating it.

v0.55.1 — super-ux

Choose a tag to compare

@github-actions github-actions released this 06 Sep 20:39
a60f6b4

Family audit 2026-09-06, wave AUDIT-WAVE-0906. The operator's routing block
promises a spoken refusal for each chain — "no scenarios" / «без сценариев» for
the UX chain, "no brand" / «без бренда» (plus "draft it" / «черновиком» for
copywriting) for the copy chain — and no skill text in this pack carried any of
them.
With the routing block installed the promise held one layer up; a
standalone install advertised no opt-out at all, so an operator who wanted the
route skipped had no phrase the skill had agreed to hear.

One sentence in each of the seven bodies now states it: the operator declines
the route by saying the phrase, and the skill proceeds without the chain while
saying so — never silently. Measured before and after with the house auditor:
every body stays inside its working limit, the tightest being ux-audit
~4626/4750 and ux-flows ~4529/4750 tokens.

No description: changed, by decision rather than accident. Descriptions
pair with the umbrella's trigger table, and a dropped advertised phrase refuses
the family pin. ux-flows's description stands at 965/1024 — 965 of the 970
working limit — and is recorded here untouched for exactly that reason:
git diff -U0 over the skills shows zero changed description: lines.

repo validator checks re-measured at 4623 by running the command
docs/brand/facts.md names — the count did not move with this change, and
that is a measurement, not a restatement.

v0.55.0 — super-ux

Choose a tag to compare

@github-actions github-actions released this 05 Sep 21:27
2d80b5c

A repair for what the previous release shipped, and the gate that would have caught
it.
0.54.0 went out with its verification ledger's newest section naming v0.53.0.
This repository's own gate said nothing; the umbrella's cross-member ratchet caught it one
layer up — 3 member ledgers describe a version older than they ship, and the ratchet
stands at 2
— which is the right backstop and the wrong first line.

validate_ledger_names_its_version reads the newest ## … section, resolves the version
it names and compares it with package.json. A ledger whose newest section names an older
artifact is a release nobody re-confirmed against anything.

The first draft crashed instead of refusing. It called a fail() this module does not
have — the name belongs to a sibling repository's validator — so the plant raised
NameError and the run stopped. rc=1 either way, which is exactly why the plant looked
like it had worked. A guard that crashes has not refused anything: it stops the suite
before the rest of it can speak, and it reports a defect in itself as a defect in the
tree. Rewritten through check(), watched refusing its plant with no traceback.

Ledger section added for 0.54.0's own content, so the release it repairs is recorded
rather than skipped. repo validator checks recomputed 4621 → 4623 by running the command
docs/brand/facts.md names, not by adding two.

v0.54.0 — super-ux

Choose a tag to compare

@github-actions github-actions released this 05 Sep 21:16
1324078

Closes ssheleg/sshlg-skills#B-87 (board row), and widens two advertised triggers.

A method told the agent to click through a competitor funnel by hand, in sessions
where two browser tools are connected.
FR-01 read "open a competitor's ad, click
through, and you are in it at step one"
and named no tool for the click — while the
same repository's neighbours already name chrome-devtools for their own crawling and
claude-in-chrome is connected beside it. FR-01's whole output is a list of live
funnel URLs with the ad that led to each
: a walk a browser tool performs and a person
performs slowly.

The answer is both, and the split is the useful part. The walk is mechanical until
it is not:

  • a browser tool opens the ad's destination, follows the redirect chain and captures
    four things a screenshot loses — the final URL after redirects, every step's URL in
    order, the network requests on the paywall step (which processor, which price ids —
    the one place a funnel states its own price without a human reading it), and the ad
    that led there;
  • a human takes over at three points that are not incidental: consent walls, which
    vary by geography and are the first thing an automated walk gets stuck in; sign-in
    and paywall steps
    , where a tool cannot proceed without real credentials or a real
    card — and where FR-06 already forbids going further; and ad libraries themselves,
    which rate-limit and serve challenges to a driven browser.

So: the library is read by a person, the funnel is walked by a tool, and the walk stops
at the first wall that asks who you are. Silence here read as nobody thought about
it
, which is worse than either answer
— and the method is otherwise the most
operationally precise document in the pack.

Two advertised triggers corrected rather than added. copywriting advertised
"пост для твиттера", which demands a literal «для» an operator does not type; it now
reads "пост в твиттер". And "error text" / "текст ошибки" is named, closing a route
the umbrella measured reaching nothing. The description moves 634 → 662 of 1024, leaving
308 characters — well clear of the 60-character reserve the family's ratchet counts.

v0.53.0 — super-ux

Choose a tag to compare

@github-actions github-actions released this 04 Sep 23:18
002f5f4

Closes ssheleg/sshlg-skills#96.

A metric is built to end an argument about coverage. Then the rule that decides what a
document is ABOUT
turns out to be one line of string handling, and the number reports work
that exists as work that is missing — and the number now generates work that is fictional.

Measured: a screen inventory decided a screen was documented when a scenario named its path
as the primary entry point, taking the first backticked path from Entry point: whole.
Two scenarios name their subject with a query string — /reset-password?token=… and
/account/billing/return?invoice=&status= — so both matched no route, and two screens
that had always been documented were published as having no scenario at all.
The board row
that followed named nine screens needing scenarios: two needed nothing, and a third was one
component at two addresses, which the rule can only ever name one of. Three of nine rows
were fiction, in a number whose whole purpose was to stop people arguing about coverage from
memory.

ux-audit now carries three rules for any metric over these documents:

  • the aboutness rule is a named, exported function with a table of synthetic inputs,
    including the negative cases
    — query strings, fragments, several paths in one field,
    prose with no backticks. It was untestable while it was an inline regex, which is exactly
    why it was never tested;
  • a metric that cannot express a real state says so beside the number rather than
    counting that state as a failure. One screen at two addresses is one screen, and the
    matrix carries a derived alias routes line instead of silently ranking the second
    address undocumented;
  • a deliberate, hard-won rule is a reason to test it, not to trust it. This one had
    already replaced a looser rule twice, each time after a screen was reported covered on a
    mention rather than on a subject — and a rule with that history is the last one anybody
    re-reads.

v0.52.5 — super-ux

Choose a tag to compare

@github-actions github-actions released this 03 Sep 12:07
5fb2ee3

The committed social preview is now the umbrella's own render, byte for byte
(node test/site_test.jsPASS: site — 42 checks). Nothing about this pack changed;
the string it is rendered from did.

super-ux's role cell said "what the interface must do and how it sounds" in the
routing map — the block's first content and its highest-salience surface — while the
precedence table 362 lines below gave "how it sounds" to copywriting, and this pack's
own router text says the same split. A reader who stopped at the first table routed copy
work to /ux, on the one router pair the block works hardest elsewhere to separate. The
cell is now "what the interface must do", which is exactly what the precedence table
already said.

The umbrella carries the fixture that keeps it: no member's role may contain another
router's answer, with one declared exemption. Watched refusing the old string —
super-ux's role answers copywriting's question: "how it sounds".

Board: B-131.

Changelog

v0.52.4 — super-ux

Choose a tag to compare

@github-actions github-actions released this 01 Sep 19:49
4e1aab8

SKILL-CARD.md carries the fields Anthropic's Skills-for-enterprise guidance asks every
organisation to keep — "written so somebody who did not build this can decide". It said
0.48.3 while this package shipped 0.52.3.

Nothing read it, so it could only drift. The version moves in package.json,
plugin.json and marketplace.json on every release; the card was in no list. Measured
2026-09-01 across the family: four of nine cards were behind — this one by four minor
releases, agent-stack by ten.

The check refuses a card whose Version row disagrees with package.json, and refuses a
card that states no version at all: one a reader cannot see go stale is worse than one
that lags visibly. Watched failing before it shipped. repo validator checks
4617 → 4619, recomputed by the command the fact itself cites rather than by hand.

And the same defect as the sibling, in the same kind of place. test/validate.py
carried an invalid escape sequence — a lone backslash-pipe in a non-raw docstring — which
Python already warns about and future versions will reject. It sat in a paragraph
explaining that "the escape-awareness is the whole check". Now raw, zero escape
warnings — as agent-stack's was an hour earlier, from a paragraph explaining how to
escape a pipe.

v0.52.3 — super-ux

Choose a tag to compare

@github-actions github-actions released this 31 Aug 16:15
  • validate_front_matter_is_yaml parses all 30 shipped front-matter blocks with PyYAML
    (B-033): 7 SKILL.md, 15 commands, 8 .mdc mirrors. front_matter() reads a block line
    by line and never asks what a YAML parser would, so a : inside an unquoted scalar turns
    the whole block into an invalid mapping and ships anyway — green here, refused by every
    installer that parses YAML, and the hub copy freezes on the previous version. The family
    shipped exactly that twice in twelve days (sheleg-design 1.37.4 and 1.58.0, both
    mapping values are not allowed here), so the remedy is ported from the sibling that
    paid for it
    rather than reinvented.
  • The two guards are the ones that history says matter. It fails closed when PyYAML
    is missing, because a guard that discloses and passes when its tool is absent is the hole
    the first fix left open; and it refuses an empty walk, because globs that all match
    nothing is a moved directory rather than a clean tree. Both watched: yaml blocked at
    import, and the three globs renamed.
  • YAML_SELF_TEST is a permanent plant, not a one-off. This gate's whole claim is that
    it sees what front_matter() cannot; a parser that stopped refusing that shape would leave
    it green on a clean tree forever, so the shape is re-checked on every run.
  • PyYAML installed in both workflows: setup-python puts a different interpreter on PATH
    than the runner's system one, which is where PyYAML is preinstalled.

v0.52.2 — super-ux

Choose a tag to compare

@github-actions github-actions released this 31 Aug 02:29
  • The eval suite has dated rows instead of a vacant table (SUX-04, family audit
    2026-08-29). 28 blind trigger probes — one fresh subagent per query per model
    (haiku, sonnet), each shown only the query and the 28 installed family skill
    descriptions — scored 14/14 on both models (train 8/8, validation 6/6), with every
    raw answer recorded. Three scenario runs in fresh scratch workspaces scored 12/12
    expected-behavior lines, each re-verified by running the pack's own linters over
    the agents' outputs (s01 design chain: ux_lint.py 0 errors; s03 rewritten copy:
    brand pack is clean). test/evals/RESULTS.md carries the per-query receipts,
    the scenario evidence, and a Method section that states the limits — single
    repetition per query against a README that asks for three, model aliases rather
    than snapshot ids, and the one non-hermetic call the s02 audit itself disclosed.
  • Two changes shipped inside v0.52.1 without a line of record, and this is that
    line.
    The 0.52.1 commit was cut by a concurrent session from this working tree
    while this run's edits sat uncommitted in it, so they rode along:
    compatibility: front matter in all seven skills (SUX-02) — per-skill rather
    than one blanket string: the five UX skills name python3 3.9+ (stdlib only) for
    the linter this pack seeds, ux-flows names its optional MCPs (Figma for
    mockups, Refero/Mobbin/Lazyweb for reference screens) and what happens when they
    are absent, ux-audit states which half of the Figma check survives without the
    MCP, and the two brand skills name docs/brand/lint.py — and $schema in both
    manifests
    (SUX-05), the two schemastore spellings that resolve (the family also
    carries a claude-code-plugin.json variant, which 404s and was not copied);
    claude plugin validate --strict passes on both. Every compatibility value is
    a one-line YAML plain scalar with no colon-space sequence, parsed with
    yaml.safe_load before it ever reached a commit — the family shipped that exact
    defect twice this week (sheleg-design 1.37.4 and 1.58.0), and a planted
    colon-space here was caught by the same mapping values are not allowed here.
    Budgets measured: 153–358 chars against the standard's 500; the pinned house
    auditor returns 0 GAP on all seven. The class — a repo gate that parses shipped
    front matter as YAML — is filed as B-033 rather than claimed, because this
    run's check was manual.

v0.52.1 — super-ux

Choose a tag to compare

@github-actions github-actions released this 31 Aug 01:37
  • B-029's board row carried an unescaped | inside a backticked span
    (`Kind: copy \| layout`), and markdown splits a table row on the pipe before any
    inline parsing happens, so the code fence does not protect it. Every column after the
    break shifted by one and Status read as whatever landed in its place: a resolved row
    that a machine reads as something else, in one of the two files this pipeline treats as
    its record. Escaped.
  • Found by the family umbrella's validator on this repository's own v0.52.0 tag, while
    bumping the pin — not by anything here. validate_ledger_table_shape now asks the same
    question of both ledgers, and it is escape-aware because the first version was not: it
    counted \| as a separator and reported fourteen broken rows in files that had one,
    which is a detector nobody would have kept. Watched on the exact defect, and its limit
    measured and written down — backlog.md carries its header twice, so the guard catches
    a header that vanished entirely while a partial loss falls to the ratchet, which moved
    4488 to 4475 on that plant.