Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b6d1470
docs(agent-loop): activate REV policy persistence chunk
Abiorh001 Jul 23, 2026
67ee3ee
docs(agent-loop): amend REV policy proof scope
Abiorh001 Jul 23, 2026
27cbb5e
docs(agent-loop): bound REV policy test exceptions
Abiorh001 Jul 23, 2026
94b4e67
feat(review): persist immutable review policies
Abiorh001 Jul 23, 2026
c8db366
fix(review): harden policy persistence proof
Abiorh001 Jul 23, 2026
af09405
test(review): prove policy persistence boundaries
Abiorh001 Jul 23, 2026
35531df
test(review): close policy evidence gaps
Abiorh001 Jul 23, 2026
5417578
docs(review): publish 03P trust evidence
Abiorh001 Jul 23, 2026
2a56870
docs(review): bind machine-readable evidence
Abiorh001 Jul 23, 2026
108a216
docs(review): authorize API policy fixture repair
Abiorh001 Jul 23, 2026
0c474f1
docs(review): clarify proof-only exceptions
Abiorh001 Jul 23, 2026
b68a1e2
fix(review): align API contract policy fixture
Abiorh001 Jul 23, 2026
94722ff
docs(review): record API E2E repair
Abiorh001 Jul 23, 2026
5a29a15
test(review): repair full-suite policy compatibility
Abiorh001 Jul 23, 2026
7529d11
docs(review): authorize ART fixture ordering
Abiorh001 Jul 23, 2026
b9501b3
test(review): order ART policy fixture before publication
Abiorh001 Jul 23, 2026
ba9c624
docs(review): record complete Backend repair
Abiorh001 Jul 23, 2026
6cf3ad4
docs(review): rebind final repair evidence
Abiorh001 Jul 23, 2026
bf32258
docs(rev): authorize policy truncate guards
Abiorh001 Jul 23, 2026
fe4b144
fix(rev): guard policy truncation
Abiorh001 Jul 23, 2026
0ce636c
docs(rev): bind truncate repair evidence
Abiorh001 Jul 23, 2026
50197bf
test(rev): bind truncate guard schema fingerprint
Abiorh001 Jul 23, 2026
5ef77bb
docs(rev): authorize guarded policy test reset
Abiorh001 Jul 23, 2026
58a7335
test(rev): reset guarded policy tables
Abiorh001 Jul 23, 2026
4e05f16
docs(rev): bind guarded reset evidence
Abiorh001 Jul 23, 2026
f19b2d7
test(rev): reach policy truncate guards
Abiorh001 Jul 23, 2026
f2becbd
docs(rev): bind truncate test evidence
Abiorh001 Jul 23, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -1123,3 +1123,43 @@ AUTH/ART/CON owner plan, or frozen reference source changed.
The repaired candidate requires fresh exact-SHA internal review, deterministic
gates, evidence rebinding, push, CodeRabbit re-review, and GitHub CI before PR
#150 is ready for the user's merge decision.

## WS-REV-001-03P Internal Implementation Review - 2026-07-23

Signed run `30014647556` authorized 03P on exact main `bcf1292e`. The bounded
implementation persists immutable ReviewPolicy and RevisionPolicy facts only.
It preserves migrated legacy facts privately, permits only an atomic legacy to
canonical conversion, serializes policy writes with guide publication, refuses
lossy downgrade, and exposes no retired archival fields.

Review iterations repaired legacy activation compatibility, stamped Task
compensation isolation, deterministic PostgreSQL waiter proof, all-five-field
archival denial/non-exposure, and distinct-context direct-insert failures.
Exact code candidate `35531df254c6b25726d666a5e89eda997b97d792`
passes senior engineering, QA/test, security/auth, product/ops, architecture,
docs, reuse/dedup, test-delta, CI-integrity, and circuit-breaker review. No
finding remains. Full backend tests and coverage are intentionally deferred to
GitHub Actions; 03A has not started.

## WS-REV-001-03P API E2E Repair - 2026-07-23

PR #195's first GitHub run passed preflight and Agent Gates but API E2E rejected
the stale Project Guide policy fixture. A prospective contract amendment
authorized only `backend/scripts/api_contract_e2e.py::guide_payload`; all
lifecycle, endpoint, authorization, response, and non-policy behavior remained
prohibited. Candidate `b68a1e22b3bf373d15479784d545fcc9b5737f64`
removes the five retired inputs, uses canonical finding fields, and supplies the
two reviewed durations. Ruff and diff integrity pass, and all required internal
tracks pass on the exact candidate.

The completed Backend run then exposed shard 1's six stale 0033 head/rollback
expectations and shard 3's ART fixture policy-after-publication ordering. The
six assertions now name 0034 without changing historical targets. The ART
fixture repair was reverted after an internal scope finding, prospectively
authorized, and reapplied byte-identically: policies flush while the same guide
is draft, then its prior active/approval/effective values are restored before
Task, Submission, or CheckerRun setup. Final code candidate
`b9501b31565370306aea168ff4c218a2880e6c0b` passes the four exact Alembic tests,
the exact ART test, Ruff, diff integrity, and all internal tracks. CodeRabbit
did not perform a review because its limit was reached. Fresh GitHub and actual
CodeRabbit proof remain required.
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

## Current status

On 2026-07-22 a complete reread of the canonical Markdown and PDF specification
identified that the 02A family crossed the REV ownership boundary. REV begins
only when the current finalized checker result is `allow_review`; it consumes
the existing Submission and the same submitted/verified artifact set. Project
Guide setup, activation, Task intake, and upstream publication fencing belong to
their owning subsystems. REV reports gaps in those handoffs and does not repair
them. The attempted 02A1 runtime candidate was reverted in full.

`WS-REV-001-PLAN3` is proposed planning-only work, not canonically active. It retires
02A/02A1/02A2/02A3/02A4/02B/02C as REV implementation authorization. The first
future REV chunk is 03P: REV-owned ReviewPolicy/RevisionPolicy persistence.
Canonical start requires the signed `Loop Memory Explicit Event` workflow on
exact current main; chat and local work are not start evidence.
`WS-REV-001-03P` is active through signed `Loop Memory Explicit Event` run
`30014647556` on exact trusted main
`bcf1292e1a591e3e84bf8ee212ee7191d80741fa`. Reviewed CodeRabbit-repair
implementation candidate `f19b2d798e49e7c3ebb05a19eaa53638c61237a1`
persists only REV-owned immutable ReviewPolicy and RevisionPolicy facts and
passed every required internal review track plus focused local evidence. Candidate
`35531df254c6b25726d666a5e89eda997b97d792` is retained only as historical
pre-external-repair authorization context. GitHub Actions full-suite/coverage,
incremental CodeRabbit confirmation, and human review remain before merge.

The chunk does not implement Project Guide ownership, Task transitions,
Submission or artifact behavior, review queues or leases, Review decisions,
revision execution, FinalAcceptance, or contribution records. `03A` remains
stopped and requires a separate signed start after 03P merges.

The historical text below records the superseded PLAN2/02A state and is not
current implementation authority. Trusted main at that time was `44f2467c`, which additionally
Expand All @@ -26,11 +27,11 @@ database/concurrency boundaries. That attempted split is now retired.

## Historical dependency snapshot

Current trusted main is `14fa4316f7d984f2176657bfafd2a2dae56f944e`
At the PLAN3 snapshot, trusted main was `14fa4316f7d984f2176657bfafd2a2dae56f944e`
with sole Alembic head `0033_authorization_read_rate_control`. The bullets below describe the
older PLAN2 snapshot and are not current runtime proof.

Canonical signed loop memory currently remains stopped after merged 02A and
At that snapshot, canonical signed loop memory remained stopped after merged 02A and
names retired 02A1 as next. That projection is accurate historical automation
state but no longer a valid REV scope choice. PLAN3 is proposed—not active—and
its reviewed merge intent changes the same-initiative successor to 03P. No
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

## Status

Proposed only. It may start only through a signed `Loop Memory Explicit Event`
on exact current main after PLAN3 merges and this contract is refreshed/reviewed.
Active through signed `Loop Memory Explicit Event` run `30014647556` on exact
trusted main `bcf1292e1a591e3e84bf8ee212ee7191d80741fa`. Superseded history SHA
`94702ae492341402b725ffd6751f8f81ac68100b`
records the content-equivalent CodeRabbit-repair tree that passed every required
internal review track and focused local gate; canonical exact-SHA binding lives
in the internal review evidence after the prospective commit sequence is final.
`35531df254c6b25726d666a5e89eda997b97d792` is historical pre-external-repair
authorization context only. Publication remains gated on final evidence review
and current-head GitHub Actions, CodeRabbit, and human review.

## Goal

Expand All @@ -16,8 +23,54 @@ L1: policy immutability, duration/limit semantics, and later decision authority.

## Allowed files

To be fixed at signed start: REV-owned policy models, migration, schemas,
focused tests, and this initiative's evidence/merge-intent files only.
```text
backend/app/modules/projects/models.py
backend/app/modules/projects/schemas.py
backend/app/modules/projects/repository.py
backend/app/modules/projects/service.py
backend/alembic/versions/0034_review_revision_policy_persistence.py
backend/tests/test_alembic.py
backend/tests/test_projects.py
backend/tests/test_tasks.py
backend/tests/test_artifact_admission.py
backend/tests/conftest.py
backend/scripts/api_contract_e2e.py
docs/architecture_data_model.md
docs/template_project_guide.md
.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/{DISCOVERY,PLAN,STATUS,REVIEW_LOG}.md
.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03P-review-revision-policy-persistence.md
.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-03P-*.md
.agent-loop/merge-intents/WS-REV-001-03P.json
```

The following cross-owner files are proof-only exceptions:

- `backend/tests/conftest.py`: update only the deterministic public-schema
fingerprint for migration 0034 and register `review_policies` plus
`revision_policies` in the existing `TRUNCATE_GUARDED_TABLES` reset path so
isolated test cleanup can temporarily disable only their user triggers before
truncation and restore them immediately afterward. Do not weaken the schema
fingerprint check or reset ownership checks.
- `backend/tests/test_artifact_admission.py`: update ReviewPolicy and
RevisionPolicy fixture construction for schema compatibility. Where 0034
requires those immutable policies before publication, the owning helper may
construct the same guide as draft, flush the policies, and then assign its
previously existing active/approval/effective values before Task, Submission,
or CheckerRun setup. The final fixture state and every ART assertion and
behavior must remain unchanged.
- `backend/tests/test_tasks.py`: update only policy fixture construction and add
immutable-policy regression proof. No Task behavior may change, and the
existing stamped review, revision, and compensation-policy isolation
regression—including every compensation assertion—must remain present without
weakening.
- `backend/tests/test_projects.py`: adapt canonical policy requests/responses
while preserving every existing Project Guide activation outcome. Retired
request fields may become schema-denial tests, but activation denial may not
be removed or broadened by 03P.
- `backend/scripts/api_contract_e2e.py`: update only the existing Project Guide
policy request fixture for the canonical 03P schema. No API lifecycle step,
endpoint expectation, authorization assertion, or non-policy fixture may
change.

## Not allowed

Expand All @@ -32,15 +85,144 @@ focused tests, and this initiative's evidence/merge-intent files only.
the exact upstream context they govern without mutating that context.
- Review preference/lease duration and human revision limits/deadlines have
explicit typed semantics and are never inferred from unrelated SLA fields.
- Migration revision `0034_review_revision_policy` descends only from
`0033_authorization_read_rate` and creates no second head.
- `ReviewPolicy` adds nullable positive integer
`review_preference_window_seconds` and `review_lease_duration_seconds`,
non-null integer `max_active_review_leases_per_reviewer`, non-null boolean
`self_review_allowed`, non-null varchar(30) `reject_policy`, non-null
varchar(30) `finding_evidence_requirement`, non-null boolean
`legacy_incomplete`, nullable varchar(100) `configured_by_actor`, and nullable
timestamptz `configured_at`.
- A non-legacy ReviewPolicy requires both positive durations, capacity exactly
`1`, self-review exactly `false`, reject policy exactly `close_task`, evidence
policy exactly `optional`, `required_for_blocking`, or `required_for_all`,
decisions exactly the ordered JSON array `accept`, `needs_revision`,
`reject`, required finding fields exactly the ordered JSON array
`description`, `severity`, and non-empty configuring actor/time provenance.
`finding_evidence_requirement` defaults to `optional` when omitted while
accepting either other canonical token explicitly. Finding severity
semantics are only `blocking` and `advisory` and are documented here for the
later ReviewFinding owner; this chunk persists no finding.
- Existing ReviewPolicy rows are marked `legacy_incomplete=true`, receive no
invented duration or actor, and preserve retired values losslessly by
renaming `requires_second_review` to `legacy_requires_second_review` and
`sla_hours` to `legacy_sla_hours`. New rows are database-constrained to
`legacy_incomplete=false` and null archival fields. Only migration code may
create a legacy row: the database role loses no runtime bypass because the
trigger rejects inserts claiming `legacy_incomplete=true` after migration.
- `RevisionPolicy` retains positive integer `max_revision_rounds` and
`revision_deadline_hours`, and adds non-null `legacy_incomplete`, nullable
`configured_by_actor`, and nullable `configured_at`. Existing rows preserve
retired values losslessly as `legacy_auto_reject_after_limit`,
`legacy_allowed_resubmission_states`, and
`legacy_reviewer_reassignment_rule`; new rows require those archival fields
to be null. The runtime/API no longer accepts or exposes them. Exhaustion
cannot synthesize a Review or reject.
- All five renamed archival columns are database/migration-only: request schemas
reject them and responses never expose them. Responses expose
`legacy_incomplete`; legacy ReviewPolicy durations/configuration provenance
are nullable, while legacy RevisionPolicy retains its positive active
limit/deadline plus nullable configuration provenance. Project create/update
and active/detail reads never reinterpret an archival value as active policy.
- The migration adds these exact checks:
`ck_review_policies_fixed_v01`, `ck_review_policies_decisions_v01`,
`ck_review_policies_finding_fields_v01`,
`ck_review_policies_evidence_requirement`,
`ck_review_policies_complete_or_legacy`,
`ck_review_policies_archival_shape`,
`ck_revision_policies_positive_limits`,
`ck_revision_policies_complete_or_legacy`, and
`ck_revision_policies_archival_shape`. The JSON checks require the exact
canonical arrays, thereby rejecting missing, extra, duplicated, reordered,
null, blank, number, or object values. Direct SQL cannot insert an incomplete
new policy or arbitrary decision/state token.
- No index, unique constraint, or foreign key changes. Existing project/guide
uniqueness and composite guide-context foreign keys remain authoritative.
- Table-typed trigger functions `guard_review_policy_write` and
`guard_revision_policy_write` plus triggers
`trg_review_policies_guard_write` and
`trg_revision_policies_guard_write` lock the matching `project_guides` row
`FOR UPDATE` for insert and update. Those writes are permitted only while the
guide remains an unactivated draft (`status='draft'`, `effective_at is null`,
and `superseded_at is null`). Delete is rejected before dereferencing `NEW`
and therefore never waits on guide state.
- Statement-level `BEFORE TRUNCATE` triggers
`trg_review_policies_reject_truncate` and
`trg_revision_policies_reject_truncate` use those table-typed functions to
reject bulk erasure before dereferencing `NEW`; downgrade removes both
truncate triggers before dropping their functions. Direct-SQL proof must
exercise the rejection independently for each policy table.
- Policy `id`, `project_id`, `guide_version`, and `created_at` are immutable from
insert. Draft replacement updates the existing row only and may change only
canonical policy fields plus configuring provenance. The trigger overwrites
`configured_at` with database transaction time. It rejects moving a policy
between guide/project contexts or editing archival fields independently.
This consumes guide state read-only and changes no Guide route, activation
rule, state, or response.
- A legacy draft may convert exactly once and atomically to a complete policy:
`legacy_incomplete` becomes false, every canonical field becomes complete,
all archival fields become null, and verified configuring actor/database time
become non-null. Partial conversion, conversion after publication, or a
complete-to-legacy transition is rejected. This deliberate replacement makes
downgrade refuse because the original archival truth no longer exists.
- A migrated row is fully immutable while `legacy_incomplete` remains true.
The triggers reject every legacy-to-legacy update, including ReviewPolicy
decision/finding/fixed/evidence changes and RevisionPolicy round/deadline
changes. Direct-SQL negatives prove both tables refuse those writes and that
untouched legacy rows downgrade to their exact originals.
- Draft replacement updates `configured_by_actor` and `configured_at` to the
verified Flow `ActorContext.actor_id` and database time. Current project setup
does not expose canonical `actor_profile_id`; 03P records this exact upstream
attribution gap and does not add an AUTH lookup, compatibility path, or
ActorProfile lifecycle rule.
- Two-session PostgreSQL tests exercise ReviewPolicy and RevisionPolicy insert
and update against direct guide publication in both lock orders. The
guide-row lock must serialize the operations: either the draft policy write
commits before publication, or the post-publication write is rejected. Direct
delete refusal is proved independently for both tables because delete never
waits on guide state.
- Downgrade is lossless only for migration-existing legacy rows. It locks
`project_guides`, `review_policies`, then `revision_policies` in that exact
order with `ACCESS EXCLUSIVE`, and refuses before DDL if any non-legacy policy exists,
any archival field/provenance invariant drifted, or any protected row cannot
reconstruct the exact 0033 columns. Refusal preserves schema, head, and data;
clean prior-head upgrade/downgrade/re-upgrade restores every legacy value.
- Missing upstream Task/Assignment compatibility is reported to its owner and
cannot be repaired in this chunk.
- 03P does not change Project Guide activation. Legacy policy completeness is
exposed deterministically for the later REV queue-admission owner to reject;
no activation test may assert new behavior.
- No review lifecycle transition is activated.

## Verification

Fix exact commands at start: focused model/migration tests, PostgreSQL
immutability/refusal proof, downgrade/re-upgrade proof, agent gates, and full
coverage through GitHub Actions.
```text
cd backend && .venv/bin/alembic heads
cd backend && .venv/bin/pytest -q tests/test_alembic.py -k review_revision_policy
cd backend && .venv/bin/pytest -q tests/test_projects.py -k 'review_policy or revision_policy'
cd backend && .venv/bin/pytest -q tests/test_tasks.py -k 'published_review_policy or stamped_policy_values'
cd backend && .venv/bin/pytest -q tests/test_artifact_admission.py::test_committed_put_and_independent_verification_are_fenced
cd backend && .venv/bin/ruff check app/modules/projects tests/conftest.py tests/test_alembic.py tests/test_projects.py tests/test_tasks.py tests/test_artifact_admission.py alembic/versions/0034_review_revision_policy_persistence.py
python3 scripts/check_stale_workstream_wording.py
python3 scripts/check_markdown_links.py
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 backend/.venv/bin/python scripts/test_agent_gates.py
git diff --check
```

Migration proof must cover prior-head upgrade, all direct-SQL constraints,
legacy-incomplete preservation, update/delete refusal, both-order independent
transaction publication races, every downgrade refusal predicate, lossless
clean-head downgrade/re-upgrade, and restoration of the sole head.
The full backend suite and repository/subsystem coverage gates run in GitHub
Actions, not locally.

The migration, application mapping, direct-SQL/concurrency proof, and active
contract documentation form one atomic L1 review unit. Splitting them would
leave either an unproved database boundary or application models incompatible
with the sole Alembic head. Reviewers use those four sections as explicit human
focus areas even when the resulting safety proof exceeds the preferred soft
diff size.

## Required reviewers

Expand All @@ -49,4 +231,5 @@ reuse/dedup, docs, test-delta, and CI integrity.

## Stop

Do not implement without a signed start on exact current main.
After focused proof, required internal reviews, trust-bundle publication, and
PR creation, stop. Do not begin 03A.
Loading
Loading