Skip to content

fix(settlement): close lane B review follow-ups - #43

Merged
kapustazh merged 1 commit into
developfrom
fix/lane-b-review-followups
Sep 8, 2026
Merged

kapustazh merged 1 commit into
developfrom
fix/lane-b-review-followups

Conversation

@selezenart

@selezenart selezenart commented Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Closes the review findings that were carried rather than fixed during B05 and
B06. Three of them, plus what seven Gate A rounds surfaced while fixing them.

The live-evidence document described a state the code does not have. It said
the Arc Mainnet profile was OFFLINE_PROTECTED; that string appears nowhere in
the codebase. packages/arc-adapter/src/profiles.ts carries enabled: false,
verification: 'UNPUBLISHED', and no chain ID, RPC, explorer, or token value at
all. The document now says exactly that, so a sponsor reads the same words the
code uses. The neighbouring FALLBACK_DIRECT_RECOVERY is a real Lane C state
and is untouched.

The settlement UI refused secrets by field name only. A credential arriving
under a benign name would have reached a component prop. PEM private keys, JWTs,
and bearer tokens are now refused by value shape wherever they appear, including
inside arrays, while transaction hashes, addresses, and digests keep rendering.

Fields that render verbatim now reject control characters — identifiers,
timestamps, digests, and evidence enums all print without sanitizeText by
design. A payload missing its required collections fails as a
SanitizationError the route renders deliberately, rather than as a TypeError
from the first .map that touches it.

The contrast claim was unproven. The axe scan disables color-contrast
because jsdom cannot compute rendered colours. test/contrast.test.ts now reads
the palette tokens and every text surface from the stylesheet and asserts WCAG
AA. Every colour clears it, the tightest being --muted at 7.88:1, and a future
palette edit that drops below 4.5 fails the test.

Scope and acceptance criteria

  • The change is limited to the stated milestone or issue.
  • Acceptance criteria are listed and satisfied.
  • No unrelated cleanup is included.

Not a milestone packet. Acceptance is the four findings above, each with tests
asserting the failure direction.

Product and security invariants

  • Tenant isolation remains fail-closed.
  • Sponsor authorization, auditability, and daily caps remain enforced where applicable.
  • Recipients cannot modify sponsor controls or access sponsor-only data.
  • No secret, token, production identifier, or personal data is committed or pasted into review prompts.
  • Any non-applicable invariant is explained below.

Invariant notes:

  • Settlement invariants are not applicable: this touches a read-only
    presentational slice and one documentation line. No settlement path, no
    external effect, no state transition.
  • Secrets: the changes strengthen the redaction boundary. Value-shape detection
    stays narrow to PEM, JWT, and bearer shapes so ordinary evidence — hashes,
    addresses, digests — keeps rendering; widening it further would start
    rejecting the data the slice exists to display.

Validation

pnpm install --frozen-lockfile: PASS (after rebase onto current develop)
pnpm --filter @oneshot/settlement-ui lint: PASS
pnpm --filter @oneshot/settlement-ui test: PASS (208 tests, 22 new)
pnpm lint: PASS
pnpm typecheck: PASS
pnpm test: PASS (55 files, 889 tests)
markdownlint-cli2 and prettier over changed paths: PASS
@oneshot/testkit-settlement evidence:b06: PASS (still green against merged B06)

Independent review evidence

Gate A — exact candidate tree before push

Seven rounds. Round seven is the tree that was pushed.

Round Tree Verdict What it produced
1 2dcc2423 PASS Contrast test hardcoded the surfaces it audits; guard missed verbatim identifiers
2 bc0d221e PASS Guard missed created_at, retrieved_at, digest; audit missed literal surfaces
3 5a05e775 PASS Guard missed the evidence enums while state was covered
4 0e057354 PASS Branch base stale; rebased onto current develop
5 e863a08b PASS Context identity block went stale on amend; raw TypeError on missing arrays
6 33c2cdd8 PASS Projection still threw raw TypeError; made it a structured failure
7 the pushed tree PASS Two nil-impact nits, disclosed below
  • Base commit SHA: 48391e4968675764632627716e580988a271c13d
  • Candidate tree SHA: decd4a0d9fe70fd09a23eea95cc5e199930d6d3b
  • Candidate commit SHA: 043160c925cec0e21e5d7e5ac7b4a3f299abfa1b
  • Reviewer tool: free-pi-cli
  • Reviewer model: deepseek-v4-flash
  • Verdict: VERDICT: PASS
  • Findings or residual risks: no blocking findings. Two non-blocking, carried:
    1. assertNoControlCharacters would throw a raw TypeError if an array
      element were null. The contract bounds elements to objects, so impact is
      nil today.
    2. readTokens in the contrast test lets a later declaration of a token
      override an earlier one, matching CSS cascade order for the base rule but
      not for media-query overrides.

A recurring theme across these rounds is worth stating plainly: three findings
were prose claiming more than the code did. Each was closed by making the code
true rather than by softening the sentence.

  • The reviewed tree equals the committed tree.

Gate B — exact remote PR head

  • Pull request URL/number: fix(settlement): close lane B review follow-ups #43 fix(settlement): close lane B review follow-ups #43
  • Remote head commit SHA: 043160c925cec0e21e5d7e5ac7b4a3f299abfa1b
  • Remote head tree SHA: decd4a0d9fe70fd09a23eea95cc5e199930d6d3b
  • Reviewer tool: free-pi-cli
  • Reviewer model: deepseek-v4-flash
  • Verdict: VERDICT: PASS
  • Findings or residual risks: no blocking findings. Three non-blocking, carried:
    1. assertNoControlCharacters dereferences array elements without a null
      check; the contract bounds elements to objects, so impact is nil today.
    2. readTokens in the contrast test lets a later token declaration win,
      which matches the cascade for the base rule but not for media-query
      redeclarations. No media query currently recolours an audited token.
    3. One long prose line in the live-evidence document.

Milestone readiness: scope and acceptance criteria PASS, tests and required
checks PASS, security/privacy/secrets PASS, documentation and operations PASS,
ready for human review PASS. Settlement invariants are recorded NOT APPLICABLE:
this is a read-only presentational slice plus one documentation line, with no
settlement path, external effect, or state transition in the diff.

  • Gate B reviewed the current remote head and matches Gate A's approved tree, or a fresh Gate A was run for the changed tree.
  • Agent policy / repository-policy and all applicable CI checks pass.

Risk and rollback

Residual risks:

  • Value-shape detection covers PEM, JWT, and bearer shapes only. A credential in
    another shape is still caught by key name, not by value.
  • Null array elements and CSS token redeclaration, as disclosed above.

Rollback: revert the commit. The documentation line returns to its previous
wording and the slice returns to key-name-only redaction; nothing depends on the
new exports.

Human merge

  • A human owner has reviewed the evidence and will perform the merge.

Three findings were carried rather than fixed during B05 and B06.

The live-evidence document described the Arc Mainnet profile as
OFFLINE_PROTECTED, which is not a state the code has. It now states what
packages/arc-adapter/src/profiles.ts actually carries: disabled,
verification UNPUBLISHED, and no chain, RPC, explorer, or token value at
all. A sponsor reading the document should see the same words as the
code.

The settlement UI refused secrets by field name only, so a credential
arriving under a benign name would have reached a component prop. PEM
private keys, JWTs, and bearer tokens are now refused by value shape
wherever they appear, including inside arrays, while transaction hashes,
addresses, and digests keep rendering.

Fields that render verbatim now reject control characters. That covers
the identity fields, timestamps, digests, and evidence enums, which all
print without sanitizeText by design.

The accessibility scan disables axe's color-contrast rule because jsdom
cannot compute rendered colours, which left that claim unproven. A static
audit now reads the palette tokens and surfaces from the stylesheet and
asserts WCAG AA, so a future palette edit that drops below it fails.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
oneshot 043160c Sep 08 2026, 10:43 PM

@selezenart
selezenart marked this pull request as ready for review September 8, 2026 22:48
@kapustazh
kapustazh merged commit b352d9a into develop Sep 8, 2026
4 checks passed
@SuPuHe SuPuHe mentioned this pull request Sep 8, 2026
12 of 14 tasks
@kapustazh
kapustazh deleted the fix/lane-b-review-followups branch September 9, 2026 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants