Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions docs/skip-cycle-rebalance-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Skip one rebalance cycle (design only)

Status: draft design, no runtime binding. This PR must remain draft and must not
be merged as part of this follow-up. It adds no executable trading code,
configuration, identity, credential, permission, endpoint, or deployment.

## Purpose and current source evidence

A verified severe reviewer consensus may request that one identified rebalance
cycle submit **zero new orders**, including buys, sells, options, hedges and cash
sweeps. It cannot authorize orders, liquidate a portfolio, cancel existing orders,
change targets, resume trading, or clear another block. Already outstanding orders
can still fill; skipping a cycle is not a claim that broker positions are frozen.

There is no verified cycle-pause interface today. The following existing code
locations define where a future implementation would consume the flag:

- QPK `common/feature_snapshot_runtime.py:evaluate_feature_snapshot_strategy`
already returns a fail-closed strategy result before strategy evaluation when
snapshot admission fails. Add the cycle-denial decision beside this existing
pre-trade guard, before generating actionable rebalance targets.
- InteractiveBrokersPlatform `application/execution_service.py:execute_rebalance`
already checks live risk authority and wraps every submission in
`submit_claimed_order`, which requires an execution claim. The same denial must
be enforced before any plan executes and again in that existing final submission
guard, before calling its delegate. Broker adapters need equivalent enforcement
before adoption; one IBKR example does not prove fleet coverage.
- QPK `execution_kernel/guards.py` contains pure deny/allow decisions. Current IBKR
`consult_t1_live_submit` is **shadow-only** and explicitly ignores its result.
Adding a shadow denial there alone would not pause anything. Do not change
shadow behavior or present it as a functioning pause interface.

Source anchors: QPK main `ec26c1e94c8e06d758520711eba6b7d4603597ee`; IBKR main
`1bbf9ddbecddeef4f680f4bc5259bf5902e1b5dd`, read from GitHub during this review.
Comment on lines +33 to +34

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove real commit identifiers from public documentation

This source-anchor paragraph publishes real QPK and IBKR commit identifiers, and docs/unattended-followup-pr-review.md similarly publishes six exact PR heads. This repository contains a tracked LICENSE, so its own rules classify these documents as public material; AGENTS.md explicitly prohibits commit identifiers that lead back to real objects. Replace these identifiers with synthetic placeholders and retain exact-head evidence outside the public documentation.

AGENTS.md reference: AGENTS.md:L87-L89

Useful? React with 👍 / 👎.

These are source observations, not production image or runtime acceptance.

## Flag and ownership

Use a caller-owned record `skip_cycle_rebalance.v1`, keyed by the **existing
durable cycle identity**. The runtime, not model text, constructs its scope:

```json
{
"schema": "skip_cycle_rebalance.v1",
"cycle_id": "<existing durable cycle identity>",
"runtime_target": "<existing target identity>",
"account_scope_sha256": "<hash of approved account scope>",
"strategy_release": "<approved release identity>",
"snapshot_sha256": "<frozen cycle input hash>",
"skip": true,
"reason": "missing_stale_inputs",
"review_material_sha256": "<frozen material hash>",
"review_receipt_ids": ["<validated primary>", "<validated independent>"],
"recorded_at": "<UTC timestamp>"
}
```

The example is a contract, not a flag written to any runtime. Identifiers are
opaque metadata; secrets and raw account numbers never enter this record.
Allowed reasons are `data_integrity`, `risk_limit`, `missing_stale_inputs`.
Reject extra fields, duplicate JSON keys, incorrect types, missing scope, and any
`skip` value other than literal `true`. There is no `skip=false`, delete, reset,
resume, order or configuration operation exposed to the review writer.

The existing review consumer validates complete, distinct admitted reviewer roles,
current frozen material and receipts before setting a flag. All required roles
must flag the same severe category. Unverified Dot identity, a configured profile
name, missing secrets, or an advisory opinion alone cannot become authority to
write a runtime flag. If the admitted review channel is unavailable, the pre-trade
guard denies with `cycle_review_unavailable`; it does not invent a successful
consensus. No new IAM or secret access is proposed.

The future producer can only append an immutable skip record for the current
scope to an **already authorized durable store**. A repeated identical write is
idempotent; conflicting records deny and require investigation. Existing request
IDs with unknown outcomes are reconciled read-only, never replaced. If there is
no suitable existing store and producer identity, implementation/adoption stays
blocked. This design does not authorize creating either.

## Guard behavior

An admitted reader returns either a validated current-cycle skip, an authoritative
complete `absent` result for that exact key, or `unavailable`. File-not-found,
truncated listings, permission errors, timeouts and unknown writes must not be
silently interpreted as authoritative absence.

| Observed input | Guard result | Effect |
| --- | --- | --- |
| Valid skip matching every current scope field | deny `cycle_rebalance_skipped` | No new order of any side or instrument |
| Invalid, conflicting, unreadable or unresolved current lookup | deny `cycle_skip_state_unavailable` | No new order; operational alert |
| Admitted review channel unavailable | deny `cycle_review_unavailable` | No new order; operational alert |
| Authoritative absence for current key | keep original guard result | Adds no trading authority |
| Valid older-cycle record plus authoritative current absence | keep original guard result | Previous record cannot enable or disable another cycle |
| Existing guard already denies | preserve denial | Flag processing cannot change deny to allow |

Conceptually the existing guard computes:

```text
denied = original_guard_denied OR current_cycle_skip OR skip_read_unavailable
OR admitted_cycle_review_unavailable
```

On denial, return the existing blocked/no-op execution result with
`orders_submitted=[]` and the explicit reason. Do not emulate holding by setting
targets to zero or cash: existing execution logic could turn that into sells.
Do not return a buy-only prohibition: it could still permit sells. Read-only
observation and original pending-order reconciliation may continue.

Keep the skip latched for all retries of the same durable cycle. A process restart,
new invocation UUID, changed timestamp or timeout must not produce a replacement
cycle that avoids it. A flag's age never clears it for that cycle. A genuinely new
cycle uses a new existing durable identity and must satisfy every original gate;
this is not automatic approval or an auto-resume command. `RECONCILE_ONLY`, unknown
submission, risk limits, live-enable, release admission and all existing claims
remain independently binding.

Before adoption, prove that flag publication and the final submission guard use
the existing cycle/claim serialization boundary: either the skip is committed
before cycle admission, or the final submission read observes it before delegate
execution. A separate best-effort read with a check-to-submit race is insufficient.
Late flags cannot undo earlier orders; report the actual submission state and
deny subsequent submissions. If existing storage/claims cannot provide this
ordering, keep adoption blocked instead of claiming a verified pause interface.

## Required offline and adoption evidence

Implementation tests must inject fake stores and broker delegates, and assert zero
delegate calls for valid skip, malformed state, read failure, stale current
receipt, disagreement, duplicate roles, unknown writer outcome and existing
denial. Cover sell, buy, cash sweep and option paths; retries/restarts must stay
denied. Prove a different cycle cannot inherit or bypass a skip, and unchanged
absence never changes the original decision. Cover a flag appearing between
planning and submission through the existing serialized claim boundary.

This documentation-only draft does not run those tests or claim implementation.
Future binding requires the approved store/identity, all broker path coverage,
the concurrency proof and a separately authorized adoption. Until then severe
consensus keeps reporting `pause_not_available` and notifying the owner honestly.
49 changes: 49 additions & 0 deletions docs/unattended-followup-pr-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Unattended draft review — 2026-10-15

Local self-review of exact GitHub PR diffs and current check results. This is not
an independent model review, production acceptance, or a grant verification.
No merge qualifies under the owner's requested conditions; all six stay draft.
Comment on lines +3 to +5

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the internal follow-up status report outside Git

This document records a particular task's self-review, current CI status, draft dispositions and verification handoff rather than a durable runtime contract or design decision. Committing that temporary internal task report conflicts with AGENTS.md's explicit storage boundary. Keep the report outside Git and retain only reusable design or operating guidance in the published documentation; the same separation is needed for the job-completion and handoff portions of docs/unattended-owner-update-inventory.md.

AGENTS.md reference: AGENTS.md:L50-L55

Useful? React with 👍 / 👎.

Any future eligible merge must re-read all checks at the exact final head and use
`gh pr merge --squash --match-head-commit <head>` without `--admin`. A skipped gate
is not evidence that the gate passed.

| PR | Reviewed head | Observed checks | One-line disposition |
| --- | --- | --- | --- |
| QPK #672 | `0c727102b57074fab889fd156efedf2ba340f8af` | CI test success | Keep draft: deeper Dot routing/admission is unverified and the monitor executes a mutable feature-branch reference. |
| ARC #116 | `47539f27728ebd6eb8d40d8d1e3989797067a1f7` | CI test success | Keep draft: stacked on #115 and explicitly depends on unresolved issue #104 caller identity/model/material/routing admission. |
| US #601 | `295df4da6bef3e4e8ff22e95fb980a2d01035dce` | Four CI checks success; behind main | Keep draft: unadopted QPK runtime and mutable monitor reference; no verified deeper Dot route. |
| CN #330 | `6b4f0efc6c341b786a6e37a18e54171e0979c3c9` | CI test and actionlint success | Keep draft: unadopted QPK runtime and mutable monitor reference; no verified deeper Dot route. |
| HK #249 | `6c2b0b20c3ef234363e91b19279a323592a0be40` | CI success; Evidence Gate skipped | Keep draft: QPK/runtime/routing dependencies remain and the Evidence Gate has not passed. |
| Crypto #270 | `a8a413d08263fbe1d787e0d429daf6004fd0ab78` | CI test/actionlint success; Evidence Gate skipped | Keep draft: QPK/runtime/routing dependencies remain and the Evidence Gate has not passed. |

The diff review found no added trading, IAM or secret-access permission in these
six changes. GitHub issue writes are review-record/notification permissions;
existing OIDC permissions are retained, not new grants. This satisfies only part
of the requested merge conditions, and does not excuse runtime dependencies.

QPK `DotReview` selects a configured verifier or first reviewer and accepts only
agent mode before submission; its completed receipt checks request, task, owner
and provider. It cannot prove beforehand that the profile is an admitted Dot
route. Its monitor checks out `feat/advisory-review-closed-loop`. Consumer health
workflows call that same mutable branch. Consumers retain existing approved-wheel
digests, so enabling a new environment flag does not prove the installed runtime
contains the new disposition code. Do not change pins or READY variables here.

ARC #104 is an **issue**, not a PR. It remains open with unfilled acceptance items
for the caller, actual effective route, model/material authority and live receipt
verification. ARC #116 changes shipped `config/repair.json` to enable the loop
for an opt-in backend and suppresses some unconfirmed notices; without verified
adoption its new behavior must not be treated as operational recovery.

Additional concrete QPK monitor limitation: `check_lane` reads only completed
runs; a permanently queued/running review can be omitted. It also uses the latest
manual or PR run as the age anchor for a scheduled lane. Such runs can mask a
missing natural scheduled review. The independent monthly dead-man follow-up
uses expected schedule slots and detects stalled cycles without any model route.

Validation in this follow-up: QPK's review-loop/disposition/task/drift/summary
tests passed (43); ARC unittest suite passed (95). Tests use fakes. The reviewed
GitHub checks were read separately. Missing API secret availability and actual
Dot caller admission were not tested or modified. No ready conversion, merge,
production run, deployment, server access, trading operation or permission
change was performed.
Loading
Loading