Skip to content

Observe consented shadow policies before promotion - #99

Merged
unbraind merged 3 commits into
mainfrom
feat/shadow-policy-deployment
Oct 23, 2026
Merged

unbraind merged 3 commits into
mainfrom
feat/shadow-policy-deployment

Conversation

@unbraind

@unbraind unbraind commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Observe a candidate alongside the active policy on explicitly consented inputs without giving the candidate tool or mutation authority. The typed SDK and pm rl shadow register/observe/compare pin policy artifacts, consent, a frozen cohort and both-arm allowances; existing generation promotion and the recursive controller require a validated shadow comparison throughout online-bound lineages.

Correctly hashed original records previously could pass history checks while claiming inconsistent outcomes, and manifest reload omitted registration-time cohort/budget checks. The promotion gate now revalidates the evidence with the same validators used by registration and live observation.

Blocking finding Fix
Original individual receipts could claim rewards 0 and 1 for identical active/candidate actions, or falsify disagreement. One shared receipt validator resolves the consented input through the pinned policy table, verifies both actions, finite bounded rewards, same-action reward equality, disagreement/failure flags and the selected-outcome digest. Observation, retry/resume, comparison and promotion all use it.
An original consented manifest with zero allowances or an expanded cohort could bypass registration checks on reload. One shared manifest validator rechecks the exact generation pair, consent, frozen cohort and both allowances on registration and every reload. Certified SDK inventory counts actual unique observation slots, including unexpected extras; aggregate charges must match validated evidence.

Every shadow validation mismatch refuses with the exact receipt in context.item_id, the invalid context.field, and an actionable message. Invalid receipts never authorize promotion. Verification remains read-only inside the existing authoritative promotion transaction; contamination, score, approval and promotion-budget checks remain required. No parallel promotion path or autonomous switching API is added. SDK/dev dependency pins and all gate thresholds are unchanged.

Four requested real-SDK reproductions cover identical-action rewards, an original zero-budget manifest, a tampered disagreement flag, and a manifest cohort expanded after plan registration. Each fails 1/1 when only the corresponding shared validator's behavior is reverted; failures are Missing expected rejection, proving prior admission rather than a test/setup error. Restoring validation passes 4/4 with Git absent from PATH and an explicit discovery ceiling. The complete focused suite passes 25/25 at 100% shadow lines/branches/functions. Additional original-record tests cover action identity, reward bounds, failure/digest fields, slot identity, actual extra charges, both aggregate charge fields, post-registration edits, prototype-like action names and native SDK workflow-policy refusal. No SDK methods are mocked and no history records are rewritten. Typecheck, test typecheck, lint, zero duplication, docstrings, changelog checks and linked PM execution (1/1) pass.

Repacked public acceptance reuses the existing read-only, non-Git MIT unbraind/pm-context tracker copy at commit f55cdbbcf2447dae29df789e133fdbe5521a47b6 and reproduces docs/shadow-evidence.json byte-for-byte: 84 certified items, first 20 sorted IDs selected without outcome filtering (17 closed, 3 other), 20/20 active actions preserved, 20 disagreements, 0 candidate failures, 20 active + 20 candidate calls, and all 175 source files unchanged. The single repository is one independent unit, so promotion correctly refuses despite empirical means 0.15 active and 0.85 candidate. Observation JSON is 548 bytes; comparison JSON 1,278 bytes, TOON 1,127 bytes. This measures observation/gating, not learned-policy improvement. See docs/shadow-policy.md and test/shadow.acceptance.ts for reproduction.

Current-head complete CI passes at 3d6e1f8ec6487a5e949c61c93170688cd0533d00:

Complete release gate Runtime Tests Statements / lines / branches / functions
npm run release:check Node 22 744/744 100/100/100/100
npm run release:check Node 26 744/744 100/100/100/100
bun run release:check Node 26, Bun 1.3.14 744/744 100/100/100/100

All three completed job logs were independently downloaded and checked: zero failures, skips, cancellations or todos; all 50 authored source files measured; 358 declarations documented. Fresh strict tracker health, typecheck/build, lint, zero duplication, isolated identity, production audit, publish attestation, packaging, changelog and Bun graph installation pass. Current-head CodeQL passes. Previous-head gate evidence is historical only. No local full gate is claimed on the saturated host.

PM: pm-rl-shadow, under pm-rl-apvf. Revert proofs are recorded on the item; its claim is released and it remains in progress for orchestrator verification. Drafts #95 and #98 remain unchanged. No review-thread replies, mentions, merge or release. Automated reviewer skips/unavailable access are not approval.

Summary by Sourcery

Require consented, fail-closed shadow observation evidence before promoting online policy successors.

New Features:

  • Add bounded shadow deployment support through typed SDK APIs and pm rl shadow register/observe/compare commands.
  • Allow candidates to observe explicitly consented inputs while returning only the active action and withholding mutation or tool authority.

Bug Fixes:

  • Prevent candidate failures, forged or edited receipts, incomplete cohorts, budget violations, and unreserved online successors from affecting active actions or bypassing promotion controls.

Enhancements:

  • Require sealed, independently validated shadow outcome comparisons within the existing transactional generation promotion gate.
  • Bind consent, policy artifacts, input identities, generation lineage, and separate active/candidate call budgets to immutable receipts.
  • Preserve retry-safe observation semantics and reuse the existing paired evaluation and statistical promotion criteria.

Build:

  • Package the new shadow SDK artifacts, documentation, example configuration, and acceptance evidence.

CI:

  • Extend the test suite with shadow observation, receipt integrity, budget, concurrency, lineage, CLI, and non-Git promotion coverage.

Documentation:

  • Document the shadow consent, budget, bounded policy, receipt, comparison, and promotion contract.

Tests:

  • Add public-tracker acceptance validation and comprehensive fail-closed regression coverage for shadow deployment and promotion.

Chores:

  • Record the shadow feature specification and implementation history in project metadata.

Summary by cubic

Adds a shadow observation mode that lets a candidate policy see the same explicitly consented inputs as the active policy without gaining tool or tracker mutation authority. Online candidates now need a sealed, validated shadow outcome comparison, revalidated against evidence and budgets, through the existing promotion transaction before they can replace the incumbent in that lineage.

New Features

  • Adds pm rl shadow register/observe/compare and typed SDK exports registerShadowDeployment, observeShadow, and compareShadow for bounded declarative lookup policies.
  • Consent pins the exact generation pair, both policy digests, minimized input hashes, and separate active/candidate call allowances.

Behavior

  • Candidate failures preserve the active action and consume the reserved candidate attempt; identical retries add no calls.
  • Conflicting outcomes, edited evidence, incomplete cohorts, and forged aggregate receipts refuse with stable codes and remedies.
  • The shadow requirement follows the lineage: any successor of an online-bound incumbent refuses without shadow evidence, blocking recursive-controller bypasses.
  • Offline recipe selection keeps its existing contract; promotion still uses the existing generation gate.

Written for commit 3d6e1f8. Summary will update on new commits.

View guided diff Turn on auto-fix

@sourcery-ai

sourcery-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Sorry @unbraind, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 3 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: ffd4f735-c3a9-42d4-8160-0549cd79ad11
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@sourcery-ai

sourcery-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR introduces a bounded, consented shadow-deployment workflow for comparing an inert candidate lookup policy with the active policy, persists immutable dual-arm observations and receipts, and requires the validated comparison to pass through the existing transactional evaluation and generation-promotion gate before switching.

Sequence diagram for consented shadow observation and promotion

sequenceDiagram
    actor Operator
    participant SDK as Typed SDK or CLI
    participant Store as PM SDK Store
    participant Eval as Evaluation Plan
    participant Gate as Generation Promotion Transaction

    Operator->>SDK: registerShadowDeployment(deployment, plan)
    SDK->>Store: Verify immutable consent and creation history
    SDK->>Store: Reserve active and candidate call allowances
    SDK->>Eval: registerEvaluationPlan(plan with shadow digest)
    Operator->>SDK: observeShadow(candidate, input)
    SDK->>Store: Read sealed deployment and certified generations
    SDK->>SDK: Evaluate bounded active and candidate lookup tables
    SDK->>Store: Seal per-member observation receipt
    Note over SDK: Return active_action only
    Operator->>SDK: compareShadow(candidate)
    SDK->>Store: Read complete frozen cohort
    SDK->>Eval: evaluatePlan(paired observations)
    SDK->>Store: Seal comparison receipt
    Operator->>Gate: Promote candidate
    Gate->>Store: Verify sealed shadow comparison
    Gate->>Eval: Enforce existing evaluation and approval checks
    Gate-->>Operator: Promote or refuse with stable code
Loading

Flow diagram for fail-closed shadow policy deployment

flowchart TD
    A[Consent exact deployment, generation pair, inputs and budgets] --> B[Register shadow deployment and predeclared evaluation plan]
    B --> C[Observe each frozen input with active and candidate lookup tables]
    C --> D{Candidate decision and outcome valid?}
    D -->|Yes| E[Seal immutable paired observation]
    D -->|No| F[Seal candidate failure and preserve active_action]
    E --> G{Complete cohort?}
    F --> G
    G -->|No| H[Refuse comparison or promotion]
    G -->|Yes| I[compareShadow and evaluate paired outcomes]
    I --> J{Validated comparison receipt?}
    J -->|No| K[Refuse promotion; consume reserved candidate attempt]
    J -->|Yes| L[Existing transactional promotion gate]
    L --> M{Approval, contamination, score and budget checks pass?}
    M -->|No| N[Keep active generation]
    M -->|Yes| O[Promote candidate in the same lineage]
Loading

File-Level Changes

Change Details Files
Adds bounded, consent-bound shadow deployment APIs that evaluate active and candidate lookup policies with isolated authority and dual-arm budgets.
  • Introduces strict declarative policy, deployment, input, observation, and refusal types.
  • Pins generations, artifacts, inputs, evaluation members, consent history, and separate active/candidate call allowances.
  • Records immutable per-input receipts with retry-safe writes, candidate failure isolation, and complete-cohort comparison reporting.
  • Exposes typed SDK functions and pm rl shadow register/observe/compare commands with JSON/TOON output.
  • Documents the consent, artifact, budget, causal-evidence, and operational contracts.
shadow.ts
index.ts
README.md
docs/shadow-policy.md
examples/shadow-policy.json
manifest.json
package.json
Integrates shadow comparison verification into the existing evaluation and generation-promotion transaction rather than creating a separate deployment path.
  • Extends evaluation plans with an optional shadow deployment digest.
  • Recomputes and validates sealed observations and aggregate receipts inside the authoritative promotion writer flow.
  • Rejects missing, incomplete, failed, drifted, forged, or statistically insufficient shadow evidence while retaining existing contamination, approval, score, and promotion-budget checks.
  • Keeps offline evaluation and recipe-selection behavior unchanged.
evaluation-plan.ts
shadow.ts
Adds comprehensive regression and public-data acceptance coverage for fail-closed shadow observation and promotion.
  • Tests parser bounds, consent and provenance binding, immutable receipt conflicts, retry/concurrency behavior, budget accounting, candidate failures, forged evidence, and active-action preservation.
  • Exercises actual CLI handlers and promotion with Git absent from PATH.
  • Validates a read-only 175-file public tracker copy, 20 selected items, dual-arm charges, aggregate evidence, and refusal due to one independent correlation unit.
  • Adds reproducible evidence and PM feature/history records.
test/shadow.test.ts
test/shadow.acceptance.ts
docs/shadow-evidence.json
.agents/pm/features/pm-rl-shadow.toon
.agents/pm/history/pm-rl-shadow.jsonl

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@unbraind unbraind left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: BLOCK
FINDINGS:

  • [blocking] shadow.ts:165 — Individual receipts are trusted without validating actions, rewards or disagreement against the policies — correctly hashed original receipts claiming rewards 0 and 1 for identical active/candidate actions can produce a promotable comparison.
  • [blocking] shadow.ts:127 — Loaded manifests omit the registration-time cohort and budget checks — a shadow-tagged evaluation plan plus an original consented manifest with zero allowances can observe ten members and authorize promotion despite exceeding both budgets.
    SUMMARY: The PR adds consented shadow observations and comparison receipts required for online promotion. The inspected tests cover failures, retries, concurrency and non-Git promotion, but miss these original-record validation bypasses; tests were not executed.

Review by a read-only codex review agent (gpt-6.1-sol), posted by the orchestrator; the PR returns to its author agent for the fixes.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@unbraind unbraind left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orchestrator review (built-in Claude review agent, verified by the orchestrator; bots are not waited for since 2026-10-22):

VERDICT: MERGE
Orchestrator re-review of the fix delta (9a6a39f → 3d6e1f8): APPROVE. Both blocking findings from the codex review are resolved.

  • Receipts: every observation passes one validateObservation before it is sealed, on retries and whenever it is read back (comparison, promotion gate). The recorded active/candidate actions must equal what the declared policies produce for the consented input, identical actions cannot carry different rewards, rewards stay within the plan bounds, and the disagreement flag, failure code and outcome digest are recomputed rather than trusted. A tampered receipt is a typed shadow_drift naming the receipt and field.
  • Manifests: registration, reload and resume all run one validateDeployment: consent for the exact deployment digest, generation/incumbent binding, frozen cohort membership, both budget allowances against the cohort, the actual sealed observation count against each allowance, and only cohort-derived receipt ids. A zero-allowance manifest, or a cohort that grows after registration, is refused before promotion.
  • Revert proofs: each of the 4 regressions fails alone when its fix is reverted; CI npm (22, 26) and bun 744/744 each, coverage 100%. Public-data replay unchanged (20 observations, 40 charged calls); promotion correctly refused.

@unbraind
unbraind merged commit ba69b61 into main Oct 23, 2026
9 checks passed
@unbraind
unbraind deleted the feat/shadow-policy-deployment branch October 23, 2026 08:52
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