NORTHSET

Proof-of-Pass Receipt — M-008

CONTRIBUTOR SELF-RUN — NOT MAINTAINER VERIFICATION

Receipt ID
M-008
Run start
2026-07-12T01:49:17.299Z
Run finish
2026-07-12T01:51:33.547Z

Project

RaspberryPiFoundation/blockly-samples

Work

workspace-search buttons need type=button · PR #2748

Verification execution

runtime: northset-oss executor v0
human operator: aeziz

Code

base
c37ab067e848da5e8b136d4cf16d8cdffc653ee5
recorded patch commit
db5ccc98b2dcb5751fb2121075e067e0439ced40
declared metadata; not execution-bound
patch diff SHA-256
sha256:d171e1897e488dbb5f732e13f892ab2380eec800be4d4aea07862dd413fad922
bound to executed patch bytes

Environment

image reference
node:22-bookworm
repository digest
node@sha256:a25c9934ff6382cd4f08b6bc26c82bf4ea69b1e6f8dabfb2ead457374127c365
network
phaseA:bridge,phaseB:none

Declared checks

Execution summary
1/1 declared command returned exit 0 in the recorded environment

  1. npm run test --workspace=@blockly/plugin-workspace-search

    exit 0 · 6.5s

unclassified executor time (derived residual) 2m09s

run wall (derived from recorded timestamps) 2m16s

PASS — 1/1 declared command

Every command listed returned exit 0 in the declared environment. Only the listed commands are in scope. Unlisted test, lint, typecheck, build, coverage, compiler, full-suite, and CI gates are not implied or recorded.

Public scope interpretation

The declared network-off check runs the workspace-search plugin's Mocha unit suite (17 tests including the new button-type regression test) on Node 22, after a disclosed online phase-A install (npm ci + the plugin's build, npm cache redirected to /workspace/.npmcache). It does not run the full monorepo test/lint/format matrix; upstream CI additionally runs Node 22 and 24, eslint, and prettier --check across all packages.

Record details

payment
none · not merge-contingent
redactions
1 email
Bundle contents digest
sha256:58c3a6dd0c2e142a486cdf7c7e112fa6aa75affcc6c77a139fd5a694cf0cd64c
Signed asset SHA-256
sha256:78d81249cc1b429983365ad72de44971530936d65e938f42cdc75b8e1eb56638
Signed provenance recorded
verified 2026-07-14T14:21:48Z

NOT INCLUDED

  • Does not prove code quality
  • Does not prove security
  • Contributor self-run record of Northset's own contribution; not the maintainer's verification.
  • The declared network-off check runs the workspace-search plugin's Mocha unit suite (17 tests including the new button-type regression test) on Node 22, after a disclosed online phase-A install (npm ci + the plugin's build, npm cache redirected to /workspace/.npmcache). It does not run the full monorepo test/lint/format matrix; upstream CI additionally runs Node 22 and 24, eslint, and prettier --check across all packages.

Signed bundle

Download signed bundle

Verify this receipt

gh attestation verify run-record-M-008.tar.gz --repo northset-oss/verification-pilot --signer-workflow northset-oss/verification-pilot/.github/workflows/attest-bundle.yml

Attestation confirms that Northset's signing workflow produced this exact bundle. The signer does not witness the recorded run, and verification does not turn it into maintainer verification.

QR → receipt page
Northset contributed this fix and ran its declared checks. Contributor self-run. Not maintainer verification.

Evidence of what ran — not a verdict that the code is good.

SELF-FUNDED FIELD-TESTING.

Committed patch.diff
diff --git a/plugins/workspace-search/src/workspace_search.ts b/plugins/workspace-search/src/workspace_search.ts
index dbb0bcb3a29fca5a61854f29dbced25d9a8e4192..81268317ae9d1fdf7bc39b7320a5b761a0d7398d 100644
--- a/plugins/workspace-search/src/workspace_search.ts
+++ b/plugins/workspace-search/src/workspace_search.ts
@@ -282,6 +282,7 @@ export class WorkspaceSearch implements Blockly.IPositionable {
     // Create the button
     const btn = document.createElement('button');
     Blockly.utils.dom.addClass(btn, className);
+    btn.type = 'button';
     btn.setAttribute('aria-label', text);
     return btn;
   }
diff --git a/plugins/workspace-search/test/workspace_search_test.mocha.js b/plugins/workspace-search/test/workspace_search_test.mocha.js
index 1e231adf8a1c6dfae6de24a5dd95061e6c140631..5ab7e35dc9747df9d664de20f286c5c7a990694a 100644
--- a/plugins/workspace-search/test/workspace_search_test.mocha.js
+++ b/plugins/workspace-search/test/workspace_search_test.mocha.js
@@ -101,6 +101,24 @@ suite('WorkspaceSearch', function () {
     });
   });
 
+  suite('createBtn()', function () {
+    test('Buttons have type button', function () {
+      this.workspaceSearch.init();
+      const nextBtn = document.querySelector(
+        'button.blockly-ws-search-next-btn',
+      );
+      const previousBtn = document.querySelector(
+        'button.blockly-ws-search-previous-btn',
+      );
+      const closeBtn = document.querySelector(
+        'button.blockly-ws-search-close-btn',
+      );
+      assert.equal(nextBtn.type, 'button');
+      assert.equal(previousBtn.type, 'button');
+      assert.equal(closeBtn.type, 'button');
+    });
+  });
+
   suite('dispose()', function () {
     test('DOM is disposed', function () {
       this.workspaceSearch.init();
Redacted stdout
=== cmd 1: npm run test --workspace=@blockly/plugin-workspace-search ===

> @[REDACTED:email] test
> blockly-scripts test

Building tests for @blockly/plugin-workspace-search
assets by path ../dist/src/*.ts 8.94 KiB
  asset ../dist/src/workspace_search.d.ts 8.57 KiB [compared for emit]
  asset ../dist/src/css.d.ts 216 bytes [compared for emit]
  asset ../dist/src/index.d.ts 159 bytes [compared for emit]
assets by path ../dist/src/*.map 2.66 KiB
  asset ../dist/src/workspace_search.d.ts.map 2.36 KiB [compared for emit]
  asset ../dist/src/css.d.ts.map 158 bytes [compared for emit]
  asset ../dist/src/index.d.ts.map 141 bytes [compared for emit]
asset workspace_search_test.mocha.js 7.46 MiB [compared for emit] (name: workspace_search_test)
runtime modules 937 bytes 4 modules
modules by path ../../node_modules/ 1.2 MiB 154 modules
modules by path ./ 38.8 KiB
  ./test/workspace_search_test.mocha.js 16.8 KiB [built] [code generated]
  ./src/index.ts 124 bytes [built] [code generated]
  ./src/workspace_search.ts 18.9 KiB [built] [code generated]
  ./src/css.ts 3.08 KiB [built] [code generated]
optional modules 84 bytes [optional]
  external "timers" 42 bytes [optional] [built] [code generated]
  external "timers/promises" 42 bytes [optional] [built] [code generated]
external "assert" 42 bytes [built] [code generated]
external "jsdom" 42 bytes [built] [code generated]
external "util" 42 bytes [built] [code generated]
webpack 5.107.2 compiled successfully in 2750 ms
Running tests for @blockly/plugin-workspace-search


  WorkspaceSearch
    init()
      ✔ CSS is injected at init()
      ✔ DOM is intialized at init()
    createBtn()
      ✔ Buttons have type button
    dispose()
      ✔ DOM is disposed
    searchAndHighlight()
      ✔ Match all blocks
      ✔ Match no blocks
      ✔ Match all non-fields
      ✔ Match all field and collapsed blocks
      ✔ Preserve current, in results
      ✔ Preserve current, not in results
    next()
      ✔ next() with unset current
      ✔ next() wrap around
    previous()
      ✔ previous() with unset current
      ✔ previous() wrap around
    focus
      ✔ close with match focuses found block
      ✔ close with no match restores focus to workspace
      ✔ close with match followed by non-match still focuses last found block


  17 passing (554ms)

Redacted stderr
=== cmd 1: npm run test --workspace=@blockly/plugin-workspace-search ===
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.
(node:29) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 17)
(Use `node --trace-warnings ...` to show where the warning was created)
Tried to move a non-movable workspace. This could result in blocks becoming inaccessible.

- - - detach here - - -

External status

Mutable upstream observation; unattested and separate from the signed run record.

PR state
MERGED
Review signal
APPROVED
CI state
SUCCESS
Upstream updated at
2026-07-13T19:03:50Z
Observed at
2026-07-14T23:05:45.867Z
MERGED

Linked maintainer review · open linked record

FOR MAINTAINERS

Request a private run

Maintain an open-source project? Send Northset a PR already in your queue. We run its repository-declared checks in an isolated container and return the run record privately. We do not modify the PR. Nothing is published without your approval. Free during the pilot.

The issue form is public. Do not include secrets or private repository details there; use email instead.

Already onboarded? Add northset-verify to a PR to request a run on that PR.

Claims boundary

This page reports scoped proof-of-pass receipt evidence. It does not prove code quality, security, full CI coverage, production readiness, or maintainer approval. An attestation confirms bundle provenance; it does not broaden the receipt's claim.

Read the full Claims Boundary policy.