Skip to content

C1-A03 — Reject inherited repair list elements - #19

Merged
LogicDuke merged 1 commit into
cockpit/c1-job-authorityfrom
repair/c1-a03-own-list-elements
Aug 16, 2026
Merged

C1-A03 — Reject inherited repair list elements#19
LogicDuke merged 1 commit into
cockpit/c1-job-authorityfrom
repair/c1-a03-own-list-elements

Conversation

@LogicDuke

@LogicDuke LogicDuke commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Finding

C1-A03 — P2 CURRENT at protected-parent HEAD:

146734b751371bc0db38ea0f37dd62ccb68d078f

Protected parent:

PR #14 — Cockpit C1

This is an isolated stacked validation PR targeting:

cockpit/c1-job-authority

It does NOT target main.

Original defect

readList obtained authorization-list entries with ordinary indexed reads.

For sparse arrays, an indexed read can walk the prototype chain.

A well-formed inherited numeric value from either a custom array prototype or
Array.prototype could therefore enter trusted repair-job authorization state.

Confirmed reachable effects on the vulnerable parent included:

  • an inherited repository path entering authorizedPaths;
  • source.edit changing from DENY to ALLOW_ONCE;
  • an ExecutionPermit being issued for the fabricated path;
  • an inherited verification command class entering
    authorizedCommandClasses and gaining command-class authority.

The defect did not grant merge or auto-merge authority.

Repair

Authorization-list elements are now read through an own-element gate using the
module's already-captured Object.hasOwn.

For ordinary arrays whose own-property introspection is truthful:

  • sparse holes reject the entire list;
  • a custom prototype cannot fill a hole with authorization;
  • Array.prototype numeric pollution cannot fill a hole with authorization;
  • inherited valid command classes cannot become command authority;
  • dense genuine own-element lists continue to work.

The internal absence sentinel is a module-private object literal, avoiding a new
mutable-global Symbol(...) dependency.

The documentation explicitly records the hostile-Proxy boundary:

a Proxy defines the observable result of both the own-property check and the
subsequent read. C1 does not claim provenance beyond the supplied object's
observable own-property report.

A lying Proxy does not widen the caller's authority because a caller capable of
supplying that Proxy can supply the same value directly as a dense own element.

Scope

Changed files only:

  • src/domain/repair-job.ts
  • docs/architecture/C1-repair-job-authority.md
  • tests/domain/job-authorization-invariants.test.ts

No other production file changed.

C1-A01 remains FIXED and unchanged.

C1-A02 remains FIXED and unchanged.

No merge execution.
No auto-merge authority.
No GitHub mutation authority.
No filesystem/process/provider authority.
No authentication.
No replay store.
No workflow-state machinery.
No PR #10 transport work.
No unrelated refactor.

Independent validation

A separate validator that did not implement the repair independently:

  • reproduced the original C1-A03 defect on exact protected-parent HEAD;
  • reproduced custom-array-prototype path fabrication;
  • reproduced Array.prototype numeric pollution;
  • reproduced inherited command-class authority;
  • proved the vulnerable behavior reaches ALLOW_ONCE with a permit;
  • verified the repaired ordinary-array paths fail closed;
  • verified dense own arrays continue to work;
  • verified hostile getter / Proxy failure paths remain total;
  • identified two P3 documentation/hygiene follow-ups;
  • independently revalidated those follow-ups;
  • classified both P3 follow-ups FIXED;
  • classified C1-A03 FIXED;
  • found no remaining CURRENT P0/P1/P2/P3 finding;
  • made zero edits.

Final independent result:

PASS

Validation

Actual final results at commit:

14b4fb3674c6409bc29ca2061221e0a5b2030b7a

Check Result
Focused C1/A03 tests PASS — 159 tests / 4 files
npm run typecheck PASS
npm run lint PASS
npm test PASS — 867 tests / 15 files
npm run build PASS
npm audit 0 vulnerabilities
git diff --check clean

Passing tests are evidence, not absolute proof.

Quarantine

This PR is a stacked validation PR.

It must pass:

  • GitHub CI;
  • independent external review;
  • Codex review;
  • CodeRabbit review;
  • policy/evidence gate;

before it may reach READY_FOR_MERGE.

MERGE IS OPERATOR-ONLY.

No AI agent is authorized to merge this repair PR.

No auto-merge.

A PASS permits only an operator decision to merge this exact repair PR into the
protected parent.

After any operator merge, the protected parent PR's new HEAD must be re-audited.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Strengthened authorization-list validation to reject missing, sparse, or inherited entries.
    • Prevented authorization checks from accepting values supplied through unexpected prototype properties.
    • Improved resilience when authorization data cannot be safely inspected or read.
    • Existing merge and auto-merge protections remain unchanged.
  • Documentation

    • Clarified authorization validation behavior and known limitations involving inconsistent proxy behavior.

`readList` obtained each authorization-list entry with an ordinary indexed
read, which walks the prototype chain. At a sparse hole that resolved whatever
a custom array prototype — or `Array.prototype` itself — carried at that
numeric key, so a value the operator never supplied could enter the trusted
`RepairJobAuthorization` snapshot as an authorized path or command class and
reach `ALLOW_ONCE` with an `ExecutionPermit` bound to the fabricated operand.

Entries are now obtained through `readOwnElement`, which gates the read behind
the module's already-captured `Object.hasOwn` and reports absence with a
module-private sentinel rather than collapsing it into `undefined`, so the list
refuses a missing element itself instead of relying on the element reader. A
sparse hole rejects the whole list: never skipped, defaulted, or filled from
the prototype chain. Dense own lists are unaffected.

The guarantee is documented at the strength the code proves. It holds for any
array whose own-property introspection is truthful; a Proxy defines the
observable result of both the own check and the read, so one that misreports
ownership can still pass an inherited value through. That widens nothing — such
a caller can supply the same value as a dense own element — and the comment and
architecture text now say so rather than claiming an atomic observation.

The sentinel is a bare object literal, so it adds no call into a mutable global
and keeps the module's captured-intrinsic discipline.

Merge stays OPERATOR_REQUIRED, auto-merge stays DENY, and C1-A01 and C1-A02 are
untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2538d20a-5a78-4b4a-9c7f-9dde925a6ad0

📥 Commits

Reviewing files that changed from the base of the PR and between 146734b and 14b4fb3.

📒 Files selected for processing (3)
  • docs/architecture/C1-repair-job-authority.md
  • src/domain/repair-job.ts
  • tests/domain/job-authorization-invariants.test.ts

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Authorization-list validation now requires own indexed properties. Sparse holes, inherited values, and throwing ownership or element reads are rejected. Tests cover arrays, prototypes, access traps, Proxies, module evaluation, and existing merge barriers.

Changes

Authorization list validation

Layer / File(s) Summary
Guarded indexed-element reading
src/domain/repair-job.ts
Adds readOwnElement and a private sentinel for guarded indexed reads.
Authorization list integration
src/domain/repair-job.ts
Uses guarded reads during list validation and documents sparse-array and Proxy behavior.
Invariant coverage and documentation
tests/domain/job-authorization-invariants.test.ts, docs/architecture/C1-repair-job-authority.md
Adds coverage for inherited values, sparse holes, hostile traps, getters, Proxies, module evaluation, and existing authorization barriers. Updates the architecture documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 14b4f

The authorization-list change is localized and all reported validation checks pass; no actionable merge-blocking risk remains beyond normal checks and review.

Poem

A rabbit checks each list with care,
No borrowed values hiding there.
Sparse holes thump, traps stay still,
Dense own entries pass the drill.
Merge gates keep their guarded will.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: rejecting inherited repair list elements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch repair/c1-a03-own-list-elements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@LogicDuke

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@LogicDuke

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 14b4fb3674

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@LogicDuke
LogicDuke merged commit cc14f2b into cockpit/c1-job-authority Aug 16, 2026
2 checks passed
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.

1 participant