Skip to content

Releases: antrixy/headerwright

v0.1.7 — a delete path no longer requests permissions

Choose a tag to compare

@antrixy antrixy released this 07 Sep 22:25
52a2eaf

Closes FINDING-028 and FINDING-024. They were one line, not two.

diffDomainGrants() computed its two sides from different questions: toRevoke
read profile MEMBERSHIP, toRequest read GRANT STATE alone. So toRequest was
every ungranted domain in the resulting set, with no reference to what the
user had just done. A delete cannot add a domain, so it had nothing new to
want, and requested anyway — one approval on a delete confirmation granted
four domains the user never approved. The same filter re-requested the whole
legacy set on any edit, silently, because a previously-approved origin
re-grants without a dialog.

const toRequest = [...after].filter((d) => !before.has(d) && !granted.has(d));

Delete never requests. Save requests only newly-typed domains. Import
requests only domains the previous set did not reference. Recovery for a
denied or legacy domain is the chip, which is what the migration notice
already told users to use.

Also FINDING-032: the selftest's source-text scans could not tell a use from
a mention. Deleting FINDING-022's fix while a comment named it kept the suite
green — a false pass on the tripwire built to stop exactly that regression.

No new capability. No new permission. The extension still has no webRequest.

Selftest 273 -> 281, three mutation passes, browser sitting G with
predictions pre-registered before Chrome opened.

v0.1.6

Choose a tag to compare

@antrixy antrixy released this 04 Sep 02:41
4fc0f1f

Fix

  • The master toggle and status line no longer scroll out of view. The popup was three elements in normal flow, so once the profile list overflowed, both the on/off control and the X/Y domains granted readout left the viewport (FINDING-022). The list now scrolls between a fixed header and a fixed footer. This was reached sooner than expected: v0.1.5's collision marker costs roughly 110px per card, so two colliding profiles could push Add profile below the fold at three profiles, not six. Verified against that exact configuration.

  • Two refusal messages no longer describe a state that isn't happening. Saving a colliding profile, and importing a file containing a collision, both reused the wording written for the per-profile card marker — which reports that a stored profile is not applying (FINDING-026). Neither case is that: nothing had been saved, nothing had been imported, and on import the message could appear directly beneath cards that legitimately did say "Not applying". Both now describe the refused action and name what to change. The import message also stated the problem twice and ended in a double period; both are corrected. The card marker's wording is unchanged.

Change

  • The subdomain migration notice now names its visual marker. It closes with "Click any underlined domain below to re-approve it", and domains carrying a pre-0.1.4 grant are the only ones underlined. No behaviour change; the notice was already correct, and this makes the domains it counts identifiable.

Notes

  • No new permissions. The manifest is unchanged: declarativeNetRequestWithHostAccess and storage, with host access requested per-domain at grant time. No webRequest; the extension cannot read your traffic.
  • v0.1.5's notes said the four-surface gap was "being addressed in the next release". This release does not close it. A colliding profile still shows a green domain dot, is counted in the "domains granted" total, and the status line still reads "applying" — the per-profile marker remains the only surface reporting the collision. Closing it means the status line and badge reporting how many profiles were skipped, which is new signal rather than corrected signal, so it is queued rather than patched.
  • Known limit: with many profiles, a delete confirmation can render below the visible area, with nothing indicating that the popup continues below (FINDING-030). Not a regression — it was also off-screen before this release — but the pinned footer now reads as the end of the popup.
  • Browser evidence for this release is in test/EVIDENCE.md (v0.1.6 — sitting E). Predictions were frozen before the browser opened (test/RUNBOOK-2026-09-04-v016.md); 12 of 13 were right, and the wrong one is recorded with its original wording.
  • FINDING-023, a claim that domain chip tooltips never render, was withdrawn during this cycle as not reproducible. The tooltips render. The migration notice change above stands on its own merits.
  • Selftest is 273 checks, 32 of them for this change. The new logic also passes a 31-mutation pass, re-runnable via test/mutate-collisions.py.
  • Known open items are tracked in FINDINGS.md (024, 025, 027–031); none block this fix.

v0.1.5

Choose a tag to compare

@antrixy antrixy released this 02 Sep 20:31
ae3c78d

Fix

  • Two profiles that write the same header on overlapping domains no longer
    pick a silent winner.
    Every generated rule carries the same DNR priority,
    and Chrome does not standardise ordering between rules with the same action
    and priority — so one profile's header applied, the other silently did
    nothing, and the popup showed both as applying (FINDING-021). v0.1.5 refuses
    the configuration instead of letting Chrome choose: a colliding pair applies
    neither header, both profiles are marked in the popup with the header
    name and the other profile's name, and a save or import that would create a
    collision is refused with the same explanation. Domains overlap the way rules
    do — example.com overlaps api.example.com, notexample.com does not.
    Verified on the wire.

Migration

  • This can affect you without your having changed anything. v0.1.4's
    subdomain fix made profiles overlap that did not overlap before —
    example.com and api.example.com is the common case — so a pair that
    worked under v0.1.3 may be marked after updating, with neither header
    applying until the header or the domains are changed in one of them. The
    refusal is reversible, and editing an unrelated profile is not blocked while
    a collision exists.

Notes

  • No new permissions. The manifest remains declarativeNetRequestWithHostAccess
    and storage, with host access requested per-domain at grant time. No
    webRequest; the extension cannot read your traffic.
  • A colliding profile still shows a green domain dot, is counted in the
    "domains granted" total, and the status line still reads "applying" — the
    per-profile marker is the only surface reporting the collision. Being
    addressed in the next release (FINDING-022, FINDING-026).
  • Full wire evidence for this release is in test/EVIDENCE.md (v0.1.5 —
    sitting D). Predictions were frozen before the browser opened
    (test/RUNBOOK-2026-09-01-v015.md); 13 of 15 were right, and the 2 wrong
    ones are recorded with their original wording.
  • Selftest is 241 checks, 36 of them for this change, including a control that
    notexample.com is not treated as overlapping example.com. The new logic
    also passes an eleven-mutation pass, re-runnable via
    test/mutate-collisions.py.
  • Known open items are tracked in FINDINGS.md (022–027); none block this fix.

v0.1.4

Choose a tag to compare

@antrixy antrixy released this 30 Aug 17:03
d74928b

v0.1.4

Fix

  • Headers now apply on subdomains of a granted domain. Under v0.1.3, a
    profile scoped to example.com applied on the apex but silently failed on
    api.example.com — the host permission did not cover the hosts the rule
    matched (FINDING-018). v0.1.4 requests *://*.<domain>/* alongside the
    apex, so a granted domain covers its subdomains. Verified on the wire.

Migration

  • Domains granted under v0.1.3 are shown as gray ("not covered yet") after
    updating, with a notice, and apply again once re-approved with one click.
    Existing grants are preserved across the update; nothing is silently lost.

Notes

  • No new permissions. The manifest remains declarativeNetRequestWithHostAccess
    and storage, with host access requested per-domain at grant time. No
    webRequest; the extension cannot read your traffic.
  • Full wire evidence for this release, including the upgrade path and the
    reconciliation behavior, is in test/EVIDENCE.md (v0.1.4 — sitting C).
  • Known open items are tracked in FINDINGS.md (021–025); none block this fix.

v0.1.3

Choose a tag to compare

@antrixy antrixy released this 13 Aug 18:18
8734115

Store listing only. No functional change.

The extension name now states what it does, so it can be
found by people searching for a header editor rather than
only by people who already know the name.

manifest.json: name, version.

v0.1.2

Choose a tag to compare

@antrixy antrixy released this 08 Aug 17:00
74f6063

Fixes

  • Generated profile ids could exceed Chrome's rule-id range after importing a
    profile at the maximum id, which caused every subsequent rule update to fail
    silently. Ids are now allocated from the lowest free value.
  • Duplicate domains within a profile were stored, displayed and exported as
    duplicates, so the chip list and the domain count disagreed on screen.
    Domains are now deduplicated, which brings the exported file into line with
    the set semantics the format already specified. No conforming file's bytes
    change.
  • Imports larger than Chrome's 5,000-rule limit were accepted and silently
    truncated, applying fewer rules than configured while reporting success.
    Over-cap imports are now refused with an exact reason, and profiles can no
    longer be added past the limit.
  • The popup showed stale status while open: a sync failure arriving after the
    popup rendered left it reporting that rules were applying. It now updates in
    place.
  • Deleting a profile now asks for confirmation. Delete is unrecoverable and
    was the only destructive action without one.
  • Exporting now states that header values are saved in plain text.

v0.1.1

Choose a tag to compare

@antrixy antrixy released this 05 Aug 03:20
192f175

Invariant-repair patch. Fixes only, no new capability.

  • Edit path now reconciles host permissions; a domain removed during an edit
    no longer keeps its grant, and a domain another profile still references is
    retained
  • Header name and value validation tightened to the HTTP token set and to
    reject control characters; rule-id range enforced on import
  • Rule sync failures are caught and surfaced; the badge no longer shows ON
    when Chrome rejected the rule registration
  • Ungranted domain chips are now clickable to request access, replacing an
    undiscoverable Edit-then-Save recovery path
  • Rule sync calls serialized

Selftest suite: 113 checks, count tripwire.

Verified against live traffic (postman-echo.com) and a written smoke script
(test/SMOKE.md) before tagging.

v0.1.0

Choose a tag to compare

@antrixy antrixy released this 31 Jul 00:35
ec0755b

Initial release.

  • Header profiles: set / append / remove request headers, scoped per domain
  • Optional per-site host permissions — nothing granted at install
  • Master toggle with state badge
  • Canonical JSON import/export (key-sorted, byte-stable)
  • declarativeNetRequest only; no webRequest permission
  • Selftest suite: 47 checks, count tripwire

Verified against live traffic (httpbin.org) before tagging.