From ae7e0a1d9ec2804ec32a6b262197d685f137550a Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 14:46:58 +0100 Subject: [PATCH 01/14] Add post-submit policy approval APIs --- .agent-loop/LOOP_STATE.md | 16 +- .agent-loop/REVIEW_LOG.md | 30 ++ .agent-loop/WORK_QUEUE.md | 6 +- .../CHUNK_MAP.md | 2 +- .../STATUS.md | 10 +- backend/app/modules/projects/repository.py | 12 + backend/app/modules/projects/router.py | 76 +++++ backend/app/modules/projects/schemas.py | 50 +++ backend/app/modules/projects/service.py | 323 ++++++++++++++++++ backend/tests/test_projects.py | 288 +++++++++++++++- docs/architecture_data_model.md | 5 +- docs/operations_project_operating_manual.md | 22 +- docs/product_first_user_flows.md | 15 +- 13 files changed, 820 insertions(+), 35 deletions(-) diff --git a/.agent-loop/LOOP_STATE.md b/.agent-loop/LOOP_STATE.md index 257e7ad7e..b6213bea9 100644 --- a/.agent-loop/LOOP_STATE.md +++ b/.agent-loop/LOOP_STATE.md @@ -4,15 +4,17 @@ - Active initiative: `WS-POL-002` - Post-Submit Checker Foundation - Active planning chunk: none -- Active implementation chunk: none -- Branch: `main` -- Status: `WS-POL-002-02` merged through PR #88 as `32af6a7` on 2026-07-11 - after internal review, current-head GitHub checks, CodeRabbit, and explicit - human merge approval. +- Active implementation chunk: `WS-POL-002-03` - Server-Owned Policy Approval + And Visibility APIs +- Branch: `codex/ws-pol-002-03-post-submit-approval-visibility` +- Status: `WS-POL-002-03` implemented and internally reviewed; evidence and PR + publication are in progress. - Last merged implementation SHA: `67fb3ca` - Last merge commit: `32af6a7` -- Current gate: none; awaiting explicit user start for the next chunk. -- Next chunk: `WS-POL-002-03` is inactive until the user explicitly starts it. +- Current gate: evidence packaging, trust bundle, PR publication, external + review, and human merge checkpoint. +- Next chunk: `WS-POL-002-04` remains inactive until `WS-POL-002-03` is merged + by explicit human approval and memory is updated. ## Operating Rule diff --git a/.agent-loop/REVIEW_LOG.md b/.agent-loop/REVIEW_LOG.md index e5b970036..eff51f9e3 100644 --- a/.agent-loop/REVIEW_LOG.md +++ b/.agent-loop/REVIEW_LOG.md @@ -1,5 +1,35 @@ # Review Log +## WS-POL-002-03 + +Status: implemented and internally reviewed on branch +`codex/ws-pol-002-03-post-submit-approval-visibility`; PR publication pending. + +Required reviewer tracks: + +- senior engineering +- QA/test +- security/auth +- product/ops +- architecture +- CI integrity +- docs +- reuse/dedup +- test delta + +Result: PASS after fixes; external review pending. + +Scope: server-owned post-submit checker policy setup visibility, approval, and +correction APIs; safe operator summaries; immutable approval provenance; and +negative authorization coverage for non-setup roles. + +Evidence: `.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md` + +Trust bundle: `.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md` + +Next chunk: `WS-POL-002-04` remains inactive until this PR is externally +reviewed, merged by explicit human approval, and followed by memory update. + ## WS-POL-002-02 Status: merged through PR #88 on 2026-07-11. diff --git a/.agent-loop/WORK_QUEUE.md b/.agent-loop/WORK_QUEUE.md index 635b72149..50802b19a 100644 --- a/.agent-loop/WORK_QUEUE.md +++ b/.agent-loop/WORK_QUEUE.md @@ -4,7 +4,8 @@ | Chunk | Title | Risk | Status | |---|---|---:|---| -| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | Inactive until explicit user start | +| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | Implemented; internal review complete; PR publication pending | +| `WS-POL-002-04` | Locked Runtime Execution And Routing Hardening | L1 | Inactive until explicit user start after `WS-POL-002-03` merge | ## Completed @@ -35,7 +36,8 @@ ## Proposed Next -Do not start `WS-POL-002-03` until the user gives an explicit start signal. +Do not start `WS-POL-002-04` until `WS-POL-002-03` is externally reviewed, +merged by explicit human approval, and followed by memory update. ## Blocked diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md index 52811d7b1..768aef126 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md @@ -12,7 +12,7 @@ reviewed, merged by explicit human approval, and followed by a memory update. |---|---|---:|---| | `WS-POL-002-01` | Post-Submit Compiler Contract | L1 | Merged | | `WS-POL-002-02` | Post-Submit Derivation Agent And Resumable Setup Integration | L1 | Merged | -| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | Proposed | +| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | In review | | `WS-POL-002-04` | Locked Runtime Execution And Routing Hardening | L1 | Proposed | | `WS-POL-002-05` | Terminal Benchmark Post-Submit Live API Proof | L1 | Proposed | diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md index 3ed82bd60..c712bf945 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md @@ -16,9 +16,13 @@ continuation, generated project `PostSubmitCheckerPolicy` persistence, automatic contributor submission handoff to the pre-review gate, and repair-only `/finalize` semantics. +`WS-POL-002-03` is implemented and internally reviewed on branch +`codex/ws-pol-002-03-post-submit-approval-visibility`; PR publication and +external review are pending. + ## Active Planning Chunk -None. +`WS-POL-002-03` - Server-Owned Policy Approval And Visibility APIs ## Active Implementation Chunk @@ -26,7 +30,7 @@ None. ## Current Implementation Branch -`main` +`codex/ws-pol-002-03-post-submit-approval-visibility` ## Chunk Status @@ -35,7 +39,7 @@ None. | `WS-POL-002-PLAN` | Merged | `codex/ws-pol-002-post-submit-checker-planning` | #85 | Defines intent, discovery, design, risks, decisions, and implementation chunks. | | `WS-POL-002-01` | Merged | `codex/ws-pol-002-01-post-submit-compiler` | #87 | Post-Submit Compiler Contract; merged as `ed52c21`. | | `WS-POL-002-02` | Merged | `codex/ws-pol-002-02-post-submit-derivation` | #88 | Post-submit derivation agent and resumable setup integration; merged as `32af6a7`. | -| `WS-POL-002-03` | Proposed | - | - | Server-owned approval and setup visibility APIs for compiled post-submit policies. | +| `WS-POL-002-03` | In review | `codex/ws-pol-002-03-post-submit-approval-visibility` | - | Server-owned approval and setup visibility APIs for compiled post-submit policies. | | `WS-POL-002-04` | Proposed | - | - | Runtime hardening for locked post-submit policy execution and routing. | | `WS-POL-002-05` | Proposed | - | - | Terminal Benchmark-style live API proof and report. | diff --git a/backend/app/modules/projects/repository.py b/backend/app/modules/projects/repository.py index ac997dcff..8c03eb0a6 100644 --- a/backend/app/modules/projects/repository.py +++ b/backend/app/modules/projects/repository.py @@ -684,6 +684,18 @@ async def get_post_submit_checker_policy_by_id( """Load a post-submit checker policy by id.""" return await self._session.get(PostSubmitCheckerPolicy, policy_id) + async def lock_post_submit_checker_policy( + self, + policy_id: str, + ) -> PostSubmitCheckerPolicy | None: + """Load one post-submit checker policy with a transactional row lock.""" + result = await self._session.execute( + select(PostSubmitCheckerPolicy) + .where(PostSubmitCheckerPolicy.id == policy_id) + .with_for_update() + ) + return result.scalar_one_or_none() + async def delete_post_submit_checker_policy( self, policy: PostSubmitCheckerPolicy, diff --git a/backend/app/modules/projects/router.py b/backend/app/modules/projects/router.py index e8ec312aa..4b86e8b04 100644 --- a/backend/app/modules/projects/router.py +++ b/backend/app/modules/projects/router.py @@ -25,6 +25,9 @@ ProjectGuideUpdate, ProjectResponse, ProjectSetupRunResponse, + PostSubmitCheckerPolicyApproval, + PostSubmitCheckerPolicyCorrectionRequest, + PostSubmitCheckerPolicySetupResponse, SubmissionArtifactPolicyApprove, SubmissionArtifactPolicyCreate, SubmissionArtifactPolicyResponse, @@ -522,6 +525,79 @@ async def get_current_pre_submit_checker_policy( raise project_http_error(exc) from exc +@router.get( + "/{project_id}/guides/{guide_id}/post-submit-checker-policy/setup", + response_model=PostSubmitCheckerPolicySetupResponse, +) +async def get_current_post_submit_checker_policy_setup( + project_id: str, + guide_id: str, + actor: Annotated[ActorContext, Depends(get_registered_actor)], + session: Annotated[AsyncSession, Depends(get_db_session)], +) -> PostSubmitCheckerPolicySetupResponse: + """Return current generated post-submit checker setup status.""" + try: + return await ProjectService(session).get_current_post_submit_checker_policy_setup( + actor, + project_id, + guide_id, + ) + except PermissionDenied as exc: + raise permission_http_error(exc) from exc + except ProjectServiceError as exc: + raise project_http_error(exc) from exc + + +@router.post( + "/{project_id}/guides/{guide_id}/post-submit-checker-policy/approve", + response_model=PostSubmitCheckerPolicySetupResponse, +) +async def approve_current_post_submit_checker_policy( + project_id: str, + guide_id: str, + payload: PostSubmitCheckerPolicyApproval, + actor: Annotated[ActorContext, Depends(get_registered_actor)], + session: Annotated[AsyncSession, Depends(get_db_session)], +) -> PostSubmitCheckerPolicySetupResponse: + """Approve the current compiled project post-submit checker policy.""" + try: + return await ProjectService(session).approve_current_post_submit_checker_policy( + actor, + project_id, + guide_id, + payload, + ) + except PermissionDenied as exc: + raise permission_http_error(exc) from exc + except ProjectServiceError as exc: + raise project_http_error(exc) from exc + + +@router.post( + "/{project_id}/guides/{guide_id}/post-submit-checker-policy/request-correction", + response_model=PostSubmitCheckerPolicySetupResponse, +) +async def request_post_submit_checker_policy_correction( + project_id: str, + guide_id: str, + payload: PostSubmitCheckerPolicyCorrectionRequest, + actor: Annotated[ActorContext, Depends(get_registered_actor)], + session: Annotated[AsyncSession, Depends(get_db_session)], +) -> PostSubmitCheckerPolicySetupResponse: + """Request correction for the current compiled post-submit checker policy.""" + try: + return await ProjectService(session).request_post_submit_checker_policy_correction( + actor, + project_id, + guide_id, + payload, + ) + except PermissionDenied as exc: + raise permission_http_error(exc) from exc + except ProjectServiceError as exc: + raise project_http_error(exc) from exc + + @router.post("/{project_id}/guides/{guide_id}/activate", response_model=ActiveGuideResponse) async def activate_guide( project_id: str, diff --git a/backend/app/modules/projects/schemas.py b/backend/app/modules/projects/schemas.py index 5262e73b5..d0fe49b08 100644 --- a/backend/app/modules/projects/schemas.py +++ b/backend/app/modules/projects/schemas.py @@ -487,6 +487,56 @@ class PostSubmitCheckerPolicyResponse(BaseModel): created_at: datetime +class PostSubmitCheckerPolicyApproval(BaseModel): + """Request schema for approving a compiled post-submit checker policy.""" + + model_config = ConfigDict(extra="forbid") + + +class PostSubmitCheckerPolicyCorrectionRequest(BaseModel): + """Request schema for requesting correction of a compiled post-submit policy.""" + + model_config = ConfigDict(extra="forbid") + + correction_reason: str = Field(min_length=1, max_length=2000) + + +class PostSubmitCheckerPolicySetupSummaryResponse(BaseModel): + """Operator-visible summary for generated post-submit checker setup.""" + + id: str + project_id: str + guide_id: str + guide_version: str + source_snapshot_id: str + source_snapshot_hash_redacted: bool = True + effective_policy_id: str + effective_policy_hash: str + pre_submit_checker_policy_id: str + pre_submit_checker_bundle_hash: str + required_checkers: list[str] + warning_checkers: list[str] + blocking_severities: list[str] + policy_hash: str | None + lifecycle_status: str + approved_by_role: str | None + approved_by_actor: str | None + approved_at: datetime | None + created_by: str + created_at: datetime + + +class PostSubmitCheckerPolicySetupResponse(BaseModel): + """Response schema for current post-submit checker policy setup state.""" + + project_id: str + guide_id: str + guide_version: str + setup_run: ProjectSetupRunResponse + post_submit_checker_policy: PostSubmitCheckerPolicySetupSummaryResponse | None + derivation_input_summary: dict[str, Any] + + class ReviewPolicyResponse(BaseModel): """Response schema for review policy records.""" diff --git a/backend/app/modules/projects/service.py b/backend/app/modules/projects/service.py index 5de40aadc..182e7f265 100644 --- a/backend/app/modules/projects/service.py +++ b/backend/app/modules/projects/service.py @@ -76,7 +76,11 @@ GuideSufficiencyReportResponse, PaymentPolicyInput, PaymentPolicyResponse, + PostSubmitCheckerPolicyApproval, + PostSubmitCheckerPolicyCorrectionRequest, PostSubmitCheckerPolicyResponse, + PostSubmitCheckerPolicySetupResponse, + PostSubmitCheckerPolicySetupSummaryResponse, PreSubmitCheckerPolicySummaryResponse, ProjectCreate, ProjectGuideCreate, @@ -113,6 +117,19 @@ r"(x-amz-|signature|credential|access[_-]?key|secret|token|password|private[_-]?key)", re.IGNORECASE, ) +CREDENTIAL_SHAPE_PATTERN = re.compile( + r"(" + r"AKIA[0-9A-Z]{16}|" + r"ASIA[0-9A-Z]{16}|" + r"sk-[A-Za-z0-9_-]{20,}|" + r"sk_live_[A-Za-z0-9]{20,}|" + r"ghp_[A-Za-z0-9]{20,}|" + r"gho_[A-Za-z0-9]{20,}|" + r"github_pat_[A-Za-z0-9_]{20,}|" + r"xox[baprs]-[A-Za-z0-9-]{20,}|" + r"eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}" + r")" +) SECRET_ARTIFACT_NAME_PATTERN = re.compile( r"(^|[._/\-])(" r"\.env[^/]*|" @@ -814,6 +831,137 @@ async def get_current_pre_submit_checker_policy( raise PreSubmitCheckerPolicyNotFound("pre-submit checker policy not found") return PreSubmitCheckerPolicySummaryResponse.model_validate(policy) + async def get_current_post_submit_checker_policy_setup( + self, + actor: ActorContext, + project_id: str, + guide_id: str, + ) -> PostSubmitCheckerPolicySetupResponse: + """Return the current generated post-submit setup status for operators.""" + require_any_role(actor, PROJECT_SETUP_ROLES) + guide = await self._get_project_guide(project_id, guide_id) + setup_run = await self._repo.get_latest_project_setup_run(project_id, guide.id) + if setup_run is None: + raise ProjectSetupRunNotFound("project setup run not found") + policy = await self._post_submit_policy_from_setup_run(setup_run) + return await self._post_submit_policy_setup_response(setup_run, policy) + + async def approve_current_post_submit_checker_policy( + self, + actor: ActorContext, + project_id: str, + guide_id: str, + payload: PostSubmitCheckerPolicyApproval, + ) -> PostSubmitCheckerPolicySetupResponse: + """Approve the current compiled project post-submit checker policy. + + Approval records are immutable. Retrying approval for an already + approved policy returns the existing provenance without rewriting it. + """ + require_any_role(actor, PROJECT_SETUP_ROLES) + guide = await self._lock_project_guide_for_setup(project_id, guide_id) + if guide.status != "draft": + raise GuideEditBlocked("only draft guides can approve post-submit checker policies") + setup_run = await self._repo.get_latest_project_setup_run(project_id, guide.id) + if setup_run is None: + raise ProjectSetupRunNotFound("project setup run not found") + if ( + setup_run.status != "post_submit_policy_compiled" + or setup_run.output_post_submit_checker_policy_id is None + ): + raise PolicySetupBlocked( + "compiled post-submit checker policy setup output is required before approval" + ) + policy = await self._repo.lock_post_submit_checker_policy( + setup_run.output_post_submit_checker_policy_id + ) + if policy is None: + raise PolicySetupConflict("project setup run post-submit policy output mismatch") + await self._validate_current_post_submit_policy_setup(guide, setup_run, policy) + if policy.lifecycle_status == "superseded": + raise PolicyEditBlocked("superseded post-submit checker policies are immutable") + if policy.lifecycle_status == "approved": + return await self._post_submit_policy_setup_response(setup_run, policy) + if policy.lifecycle_status != "compiled": + raise PolicySetupBlocked("compiled post-submit checker policy is required") + now = datetime.now(UTC) + policy.lifecycle_status = "approved" + policy.approved_by_role = self._approver_role(actor) + policy.approved_by_actor = actor.actor_id + policy.approved_at = now + await self._session.commit() + await self._session.refresh(setup_run) + await self._session.refresh(policy) + return await self._post_submit_policy_setup_response(setup_run, policy) + + async def request_post_submit_checker_policy_correction( + self, + actor: ActorContext, + project_id: str, + guide_id: str, + payload: PostSubmitCheckerPolicyCorrectionRequest, + ) -> PostSubmitCheckerPolicySetupResponse: + """Block the current compiled post-submit checker policy for correction.""" + require_any_role(actor, PROJECT_SETUP_ROLES) + guide = await self._lock_project_guide_for_setup(project_id, guide_id) + if guide.status != "draft": + raise GuideEditBlocked("only draft guides can request post-submit policy correction") + setup_run = await self._repo.get_latest_project_setup_run(project_id, guide.id) + if setup_run is None: + raise ProjectSetupRunNotFound("project setup run not found") + if setup_run.output_post_submit_checker_policy_id is None: + raise PolicySetupBlocked("compiled post-submit checker policy is required") + policy = await self._repo.lock_post_submit_checker_policy( + setup_run.output_post_submit_checker_policy_id + ) + if policy is None: + raise PolicySetupConflict("project setup run post-submit policy output mismatch") + await self._validate_current_post_submit_policy_setup(guide, setup_run, policy) + if policy.lifecycle_status == "approved": + raise PolicyEditBlocked("approved post-submit checker policies are immutable") + if policy.lifecycle_status != "compiled": + raise PolicySetupBlocked("compiled post-submit checker policy is required") + previous_policy_id = policy.id + effective_policy_id = policy.effective_policy_id + pre_submit_checker_policy_id = policy.pre_submit_checker_policy_id + now = datetime.now(UTC) + setup_run.status = "post_submit_setup_blocked" + setup_run.current_step = "post_submit_checker_policy_approval" + setup_run.output_post_submit_checker_policy_id = None + setup_run.post_submit_derivation_summary = self._safe_post_submit_derivation_summary( + { + "status": "correction_requested", + "reason": payload.correction_reason, + "post_submit_checker_policy_id": previous_policy_id, + "correction_requested_by_role": self._approver_role(actor), + "correction_requested_by_actor": actor.actor_id, + "correction_requested_at": now.isoformat(), + } + ) + setup_run.error_code = "post_submit_policy_correction_requested" + setup_run.error_summary = "post-submit checker policy correction requested" + setup_run.finished_at = now + await self._session.flush() + await self._repo.delete_post_submit_checker_policy(policy) + await self._session.commit() + await self._session.refresh(setup_run) + await self._enqueue_post_submit_setup_continuation_after_commit( + project_id=project_id, + guide_id=guide.id, + source_snapshot_id=setup_run.source_snapshot_id, + setup_run_id=setup_run.id, + effective_policy_id=effective_policy_id, + pre_submit_checker_policy_id=pre_submit_checker_policy_id, + ) + refreshed_setup_run = await self._repo.get_project_setup_run(setup_run.id) + if refreshed_setup_run is None: + raise ProjectSetupRunNotFound("project setup run not found") + refreshed_policy = await self._post_submit_policy_from_setup_run(refreshed_setup_run) + return await self._post_submit_policy_setup_response( + refreshed_setup_run, + refreshed_policy, + ) + async def create_guide_sufficiency_report( self, actor: ActorContext, @@ -2546,6 +2694,177 @@ async def _validate_project_setup_run_outputs( "project setup run post-submit policy output mismatch" ) + async def _post_submit_policy_from_setup_run( + self, + setup_run: ProjectSetupRun, + ) -> PostSubmitCheckerPolicy | None: + """Load the generated post-submit policy referenced by a setup run.""" + if setup_run.output_post_submit_checker_policy_id is None: + return None + policy = await self._repo.get_post_submit_checker_policy_by_id( + setup_run.output_post_submit_checker_policy_id + ) + if policy is None or not self._is_project_setup_run_output_match(setup_run, policy): + raise PolicySetupConflict("project setup run post-submit policy output mismatch") + return policy + + async def _validate_current_post_submit_policy_setup( + self, + guide: ProjectGuide, + setup_run: ProjectSetupRun, + policy: PostSubmitCheckerPolicy, + ) -> None: + """Require a generated post-submit policy to match current guide setup.""" + if ( + setup_run.project_id != guide.project_id + or setup_run.guide_id != guide.id + or setup_run.guide_version != guide.version + or setup_run.output_post_submit_checker_policy_id != policy.id + ): + raise PolicySetupConflict("project setup run context mismatch") + snapshot = await self._get_snapshot_for_guide( + setup_run.project_id, + guide, + setup_run.source_snapshot_id, + ) + await self._ensure_snapshot_is_latest(setup_run.project_id, guide, snapshot) + await self._validate_source_snapshot_integrity(snapshot, PolicySetupBlocked) + if setup_run.source_snapshot_hash != snapshot.bundle_hash: + raise PolicySetupBlocked("project setup run snapshot hash mismatch") + await self._validate_post_submit_continuation_payload( + setup_run, + project_id=setup_run.project_id, + guide_id=setup_run.guide_id, + source_snapshot_id=setup_run.source_snapshot_id, + effective_policy_id=policy.effective_policy_id, + pre_submit_checker_policy_id=policy.pre_submit_checker_policy_id, + ) + try: + parsed_policy = parse_locked_post_submit_checker_policy_body( + policy.policy_body, + project_id=policy.project_id, + guide_version=policy.guide_version, + policy_hash=policy.policy_hash or "", + ) + except ValueError as exc: + raise PolicySetupBlocked("post-submit checker policy hash is invalid") from exc + if ( + parsed_policy.required_checkers != policy.required_checkers + or parsed_policy.warning_checkers != policy.warning_checkers + or parsed_policy.blocking_severities != policy.blocking_severities + ): + raise PolicySetupBlocked("post-submit checker policy hash is invalid") + + async def _post_submit_policy_setup_response( + self, + setup_run: ProjectSetupRun, + policy: PostSubmitCheckerPolicy | None, + ) -> PostSubmitCheckerPolicySetupResponse: + """Build an operator-visible setup response without source-hash leakage.""" + policy_summary = None + if policy is not None: + policy_summary = PostSubmitCheckerPolicySetupSummaryResponse( + id=policy.id, + project_id=policy.project_id, + guide_id=policy.guide_id, + guide_version=policy.guide_version, + source_snapshot_id=policy.source_snapshot_id, + effective_policy_id=policy.effective_policy_id, + effective_policy_hash=policy.effective_policy_hash, + pre_submit_checker_policy_id=policy.pre_submit_checker_policy_id, + pre_submit_checker_bundle_hash=policy.pre_submit_checker_bundle_hash, + required_checkers=policy.required_checkers, + warning_checkers=policy.warning_checkers, + blocking_severities=policy.blocking_severities, + policy_hash=policy.policy_hash, + lifecycle_status=policy.lifecycle_status, + approved_by_role=policy.approved_by_role, + approved_by_actor=policy.approved_by_actor, + approved_at=policy.approved_at, + created_by=policy.created_by, + created_at=policy.created_at, + ) + return PostSubmitCheckerPolicySetupResponse( + project_id=setup_run.project_id, + guide_id=setup_run.guide_id, + guide_version=setup_run.guide_version, + setup_run=ProjectSetupRunResponse.model_validate(setup_run), + post_submit_checker_policy=policy_summary, + derivation_input_summary=await self._post_submit_derivation_input_summary(setup_run, policy), + ) + + async def _post_submit_derivation_input_summary( + self, + setup_run: ProjectSetupRun, + policy: PostSubmitCheckerPolicy | None, + ) -> dict[str, Any]: + """Return bounded setup inputs used by post-submit policy derivation.""" + summary: dict[str, Any] = { + "source_snapshot_id": setup_run.source_snapshot_id, + "source_snapshot_hash_redacted": True, + "sufficiency_status": None, + "sufficiency_finding_count": None, + "effective_policy_id": None, + "effective_policy_hash": None, + "effective_policy_required_artifact_count": None, + "effective_policy_required_evidence_count": None, + "effective_policy_forbidden_artifact_count": None, + "pre_submit_checker_policy_id": None, + "pre_submit_checker_bundle_hash": None, + "pre_submit_checker_count": None, + "pre_submit_checker_names": [], + "registered_post_submit_checker_count": len(default_checker_registry().names()), + } + if setup_run.output_sufficiency_report_id is not None: + report = await self._repo.get_guide_sufficiency_report( + setup_run.output_sufficiency_report_id + ) + if report is not None and self._is_project_setup_run_output_match(setup_run, report): + summary["sufficiency_status"] = report.status + summary["sufficiency_finding_count"] = len(report.findings or []) + if setup_run.output_submission_artifact_policy_id is not None: + effective_policy = await self._repo.get_effective_submission_artifact_policy( + setup_run.project_id, + setup_run.guide_version, + setup_run.source_snapshot_id, + ) + if effective_policy is not None and self._is_project_setup_run_output_match( + setup_run, + effective_policy, + ): + effective_body = effective_policy.effective_policy or {} + summary["effective_policy_id"] = effective_policy.id + summary["effective_policy_hash"] = effective_policy.effective_policy_hash + summary["effective_policy_required_artifact_count"] = len( + effective_body.get("required_artifacts") or [] + ) + summary["effective_policy_required_evidence_count"] = len( + effective_body.get("required_evidence") or [] + ) + summary["effective_policy_forbidden_artifact_count"] = len( + effective_body.get("forbidden_artifacts") or [] + ) + pre_submit_policy = await self._repo.get_pre_submit_checker_policy_for_effective_policy( + effective_policy.id + ) + if ( + pre_submit_policy is not None + and pre_submit_policy.source_snapshot_id == setup_run.source_snapshot_id + and pre_submit_policy.source_snapshot_hash == setup_run.source_snapshot_hash + ): + summary["pre_submit_checker_policy_id"] = pre_submit_policy.id + summary["pre_submit_checker_bundle_hash"] = ( + pre_submit_policy.compiled_bundle_hash + ) + summary["pre_submit_checker_names"] = pre_submit_policy.checker_names + summary["pre_submit_checker_count"] = len(pre_submit_policy.checker_names) + if policy is not None: + summary["effective_policy_id"] = policy.effective_policy_id + summary["effective_policy_hash"] = policy.effective_policy_hash + summary["pre_submit_checker_policy_id"] = policy.pre_submit_checker_policy_id + summary["pre_submit_checker_bundle_hash"] = policy.pre_submit_checker_bundle_hash + return summary + def _is_project_setup_run_output_match( self, setup_run: ProjectSetupRun, @@ -2578,6 +2897,9 @@ def _safe_post_submit_derivation_summary(self, summary: dict[str, Any]) -> dict[ "status", "reason", "post_submit_checker_policy_id", + "correction_requested_by_role", + "correction_requested_by_actor", + "correction_requested_at", "required_checkers", "warning_checkers", "blocking_severities", @@ -2621,6 +2943,7 @@ def _safe_bounded_summary_value(self, value: str) -> str: normalized = " ".join(value.split())[:500] if ( SECRET_REF_PATTERN.search(normalized) + or CREDENTIAL_SHAPE_PATTERN.search(normalized) or "/" in normalized or "\\" in normalized or HASH_TOKEN_PATTERN.search(normalized) diff --git a/backend/tests/test_projects.py b/backend/tests/test_projects.py index db2112d5e..6cd07d896 100644 --- a/backend/tests/test_projects.py +++ b/backend/tests/test_projects.py @@ -264,6 +264,8 @@ def test_setup_mutations_use_locked_guide_helper() -> None: "create_submission_artifact_policy", "update_submission_artifact_policy", "approve_submission_artifact_policy", + "approve_current_post_submit_checker_policy", + "request_post_submit_checker_policy_correction", "activate_guide", ] agent_methods = [ @@ -1196,8 +1198,13 @@ async def create_approved_policy_bundle( sufficiency_report=report, submission_artifact_policy=policy, pre_submit_checker_policy=compiled_pre_submit_checker, - approve=approve_post_submit_checker, ) + if approve_post_submit_checker: + post_submit_checker_policy = await approve_post_submit_checker_policy( + client, + project_id, + guide_id, + ) else: post_submit_checker_policy = None else: @@ -1222,7 +1229,6 @@ async def create_generated_post_submit_setup_output( sufficiency_report: dict, submission_artifact_policy: dict, pre_submit_checker_policy: dict, - approve: bool = False, ) -> dict: """Persist the generated post-submit setup output used by activation tests.""" async with db_session.get_session_factory()() as session: @@ -1258,10 +1264,7 @@ async def create_generated_post_submit_setup_output( blocking_severities=compiled.blocking_severities, policy_hash=compiled.policy_hash, policy_body=compiled.policy_body, - lifecycle_status="approved" if approve else "compiled", - approved_by_role="project_manager" if approve else None, - approved_by_actor="project-manager-subject" if approve else None, - approved_at=datetime.now(UTC) if approve else None, + lifecycle_status="compiled", created_by="project-manager-subject", ) setup_run = ProjectSetupRun( @@ -1299,6 +1302,23 @@ async def create_generated_post_submit_setup_output( } +async def approve_post_submit_checker_policy( + client: AsyncClient, + project_id: str, + guide_id: str, +) -> dict: + """Approve the current compiled project post-submit checker policy by API.""" + response = await client.post( + f"/api/v1/projects/{project_id}/guides/{guide_id}/post-submit-checker-policy/approve", + headers=auth_headers(), + json={}, + ) + assert response.status_code == 200, response.text + policy = response.json()["post_submit_checker_policy"] + assert policy is not None + return policy + + def test_project_setup_run_status_constraint_metadata() -> None: status_constraint = next( constraint @@ -3017,6 +3037,8 @@ async def test_project_setup_visibility_apis_require_project_setup_role( f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" "effective-submission-artifact-policy", f"/api/v1/projects/{project['id']}/guides/{guide['id']}/pre-submit-checker-policy", + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/setup", ] monkeypatch.setenv("WORKSTREAM_DEV_AUTH_ROLES", "admin") get_settings.cache_clear() @@ -3031,6 +3053,7 @@ async def test_project_setup_visibility_apis_require_project_setup_role( 200, 404, 404, + 200, ] for role in ("worker", "reviewer", "finance", "auditor"): @@ -5577,8 +5600,8 @@ async def test_draft_policy_cannot_be_approved_after_guide_activation( sufficiency_report=report, submission_artifact_policy=first_policy, pre_submit_checker_policy=pre_submit_checker_policy, - approve=True, ) + await approve_post_submit_checker_policy(project_client, project["id"], guide["id"]) activation = await project_client.post( f"/api/v1/projects/{project['id']}/guides/{guide['id']}/activate", headers=auth_headers(), @@ -6138,8 +6161,8 @@ async def test_sufficiency_warnings_require_acknowledgement( sufficiency_report=report, submission_artifact_policy=policy, pre_submit_checker_policy=pre_submit_checker_policy, - approve=True, ) + await approve_post_submit_checker_policy(project_client, project["id"], guide["id"]) activated = await project_client.post( f"/api/v1/projects/{project['id']}/guides/{guide['id']}/activate", @@ -6357,6 +6380,255 @@ async def test_activation_rejects_compiled_post_submit_checker_policy_before_app assert "approved post-submit checker policy" in response.json()["detail"] +async def test_post_submit_setup_visibility_redacts_source_hash_and_policy_body( + project_client: AsyncClient, +) -> None: + project = await create_project(project_client) + guide = await create_guide(project_client, project["id"], complete_guide_payload()) + bundle = await create_approved_policy_bundle( + project_client, + project["id"], + guide["id"], + approve_post_submit_checker=False, + ) + + response = await project_client.get( + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/setup", + headers=auth_headers(), + ) + + assert response.status_code == 200, response.text + body = response.json() + policy = body["post_submit_checker_policy"] + assert policy["id"] == bundle["post_submit_checker_policy"]["id"] + assert policy["source_snapshot_id"] == bundle["source_snapshot"]["id"] + assert policy["source_snapshot_hash_redacted"] is True + assert policy["lifecycle_status"] == "compiled" + assert policy["policy_hash"].startswith("sha256:") + assert body["derivation_input_summary"]["source_snapshot_id"] == bundle["source_snapshot"]["id"] + assert body["derivation_input_summary"]["source_snapshot_hash_redacted"] is True + assert body["derivation_input_summary"]["sufficiency_status"] == "passed" + assert body["derivation_input_summary"]["effective_policy_required_artifact_count"] == 1 + assert body["derivation_input_summary"]["pre_submit_checker_count"] >= 1 + assert "check_required_files" in body["derivation_input_summary"]["pre_submit_checker_names"] + assert body["derivation_input_summary"]["registered_post_submit_checker_count"] >= 1 + assert "policy_body" not in response.text + assert bundle["source_snapshot"]["bundle_hash"] not in response.text + for item in bundle["source_snapshot"]["items"]: + assert item["durable_ref"] not in response.text + assert item["content_hash"] not in response.text + assert "Workers submit a complete project packet" not in response.text + + +async def test_post_submit_checker_policy_approval_uses_server_provenance( + project_client: AsyncClient, + monkeypatch: pytest.MonkeyPatch, +) -> None: + project = await create_project(project_client) + guide = await create_guide(project_client, project["id"], complete_guide_payload()) + bundle = await create_approved_policy_bundle( + project_client, + project["id"], + guide["id"], + approve_post_submit_checker=False, + ) + + approved = await approve_post_submit_checker_policy( + project_client, + project["id"], + guide["id"], + ) + + assert approved["id"] == bundle["post_submit_checker_policy"]["id"] + assert approved["lifecycle_status"] == "approved" + assert approved["approved_by_role"] == "project_manager" + assert approved["approved_by_actor"] == bundle["submission_artifact_policy"]["created_by"] + assert approved["approved_at"] is not None + + monkeypatch.setenv("WORKSTREAM_DEV_AUTH_ROLES", "admin") + get_settings.cache_clear() + retry = await project_client.post( + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/approve", + headers=auth_headers(), + json={}, + ) + + assert retry.status_code == 200, retry.text + retried_policy = retry.json()["post_submit_checker_policy"] + assert retried_policy["approved_by_role"] == "project_manager" + assert retried_policy["approved_by_actor"] == approved["approved_by_actor"] + assert retried_policy["approved_at"] == approved["approved_at"] + + +async def test_post_submit_checker_policy_correction_clears_unapproved_output( + project_client: AsyncClient, + monkeypatch: pytest.MonkeyPatch, +) -> None: + project = await create_project(project_client) + guide = await create_guide(project_client, project["id"], complete_guide_payload()) + bundle = await create_approved_policy_bundle( + project_client, + project["id"], + guide["id"], + approve_post_submit_checker=False, + ) + enqueued: list[dict[str, str]] = [] + + def capture_enqueue( + *, + project_id: str, + guide_id: str, + source_snapshot_id: str, + setup_run_id: str, + effective_policy_id: str, + pre_submit_checker_policy_id: str, + ) -> str: + """Capture the recovery continuation queued after correction.""" + enqueued.append( + { + "project_id": project_id, + "guide_id": guide_id, + "source_snapshot_id": source_snapshot_id, + "setup_run_id": setup_run_id, + "effective_policy_id": effective_policy_id, + "pre_submit_checker_policy_id": pre_submit_checker_policy_id, + } + ) + return "correction-continuation-task" + + monkeypatch.setattr( + project_service_module, + "enqueue_post_submit_setup_continuation", + capture_enqueue, + ) + + response = await project_client.post( + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/request-correction", + headers=auth_headers(), + json={ + "correction_reason": ( + "Regenerate without sk-" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ) + }, + ) + + assert response.status_code == 200, response.text + body = response.json() + assert body["setup_run"]["status"] == "post_submit_setup_blocked" + assert body["setup_run"]["celery_task_id"] == "correction-continuation-task" + assert body["setup_run"]["output_post_submit_checker_policy_id"] is None + correction_summary = body["setup_run"]["post_submit_derivation_summary"] + assert correction_summary["status"] == "correction_requested" + assert correction_summary["reason"] == "redacted" + assert correction_summary["post_submit_checker_policy_id"] == ( + bundle["post_submit_checker_policy"]["id"] + ) + assert correction_summary["correction_requested_by_role"] == "project_manager" + assert correction_summary["correction_requested_by_actor"] == ( + bundle["submission_artifact_policy"]["created_by"] + ) + assert correction_summary["correction_requested_at"] + assert body["post_submit_checker_policy"] is None + assert enqueued == [ + { + "project_id": project["id"], + "guide_id": guide["id"], + "source_snapshot_id": bundle["source_snapshot"]["id"], + "setup_run_id": body["setup_run"]["id"], + "effective_policy_id": bundle["effective_policy"]["id"], + "pre_submit_checker_policy_id": bundle["pre_submit_checker_policy"]["id"], + } + ] + + async with db_session.get_session_factory()() as session: + deleted_policy = await session.get( + PostSubmitCheckerPolicy, + bundle["post_submit_checker_policy"]["id"], + ) + assert deleted_policy is None + + activation = await project_client.post( + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/activate", + headers=auth_headers(), + ) + + assert activation.status_code == 422 + assert "post-submit checker policy" in activation.json()["detail"] + + +async def test_post_submit_checker_policy_setup_apis_require_setup_role( + project_client: AsyncClient, + monkeypatch: pytest.MonkeyPatch, +) -> None: + project = await create_project(project_client) + guide = await create_guide(project_client, project["id"], complete_guide_payload()) + await create_approved_policy_bundle( + project_client, + project["id"], + guide["id"], + approve_post_submit_checker=False, + ) + endpoints = [ + ( + "get", + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/setup", + None, + ), + ( + "post", + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/approve", + {}, + ), + ( + "post", + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/request-correction", + {"correction_reason": "forged"}, + ), + ] + + for role in ("worker", "reviewer", "finance", "auditor"): + monkeypatch.setenv("WORKSTREAM_DEV_AUTH_ROLES", role) + get_settings.cache_clear() + for method, endpoint, payload in endpoints: + if payload is None: + response = await getattr(project_client, method)( + endpoint, + headers=auth_headers(), + ) + else: + response = await getattr(project_client, method)( + endpoint, + headers=auth_headers(), + json=payload, + ) + assert response.status_code == 403 + + +async def test_approved_post_submit_checker_policy_cannot_request_correction( + project_client: AsyncClient, +) -> None: + project = await create_project(project_client) + guide = await create_guide(project_client, project["id"], complete_guide_payload()) + await create_approved_policy_bundle(project_client, project["id"], guide["id"]) + + response = await project_client.post( + f"/api/v1/projects/{project['id']}/guides/{guide['id']}/" + "post-submit-checker-policy/request-correction", + headers=auth_headers(), + json={"correction_reason": "Change after approval."}, + ) + + assert response.status_code == 409 + assert "immutable" in response.json()["detail"] + + async def test_database_rejects_post_submit_checker_approved_by_non_setup_role( project_client: AsyncClient, ) -> None: diff --git a/docs/architecture_data_model.md b/docs/architecture_data_model.md index 51b16e7ba..dfa6a92f1 100644 --- a/docs/architecture_data_model.md +++ b/docs/architecture_data_model.md @@ -737,8 +737,9 @@ and compiler continuation creates `compiled` records. Guide activation requires an `approved` generated policy with setup-role approval provenance and exact `source_snapshot_id/hash`, `effective_policy_id/hash`, and `pre_submit_checker_policy_id` plus pre-submit checker bundle hash matching the -active setup context. `WS-POL-002-03` adds the server-owned approval/correction -API that moves compiled post-submit policies into that approved state. +active setup context. Server-owned approval/correction APIs move compiled +post-submit policies into that approved state or clear unapproved generated +output for regeneration. For generated setup, `PostSubmitCheckerPolicyDerivationAgent` runs only after a setup-authorized `admin` or `project_manager` approves the derived diff --git a/docs/operations_project_operating_manual.md b/docs/operations_project_operating_manual.md index 67934f18e..f5c88787e 100644 --- a/docs/operations_project_operating_manual.md +++ b/docs/operations_project_operating_manual.md @@ -42,6 +42,7 @@ Before releasing tasks: - post-submit checker derivation runs after submission artifact policy approval - generated project post-submit checker policy compiled, or unsupported checker gaps resolved - compiled project post-submit checker policy attached with source/effective/pre-submit provenance +- compiled project post-submit checker policy approved by `admin` or `project_manager`, or correction requested - review policy attached - revision policy attached - payment policy attached @@ -67,6 +68,9 @@ database queries. These endpoints require `admin` or `project_manager` access: - `POST /api/v1/projects/{project_id}/guides/{guide_id}/submission-artifact-policies/{policy_id}/approve` - `GET /api/v1/projects/{project_id}/guides/{guide_id}/effective-submission-artifact-policy` - `GET /api/v1/projects/{project_id}/guides/{guide_id}/pre-submit-checker-policy` +- `GET /api/v1/projects/{project_id}/guides/{guide_id}/post-submit-checker-policy/setup` +- `POST /api/v1/projects/{project_id}/guides/{guide_id}/post-submit-checker-policy/approve` +- `POST /api/v1/projects/{project_id}/guides/{guide_id}/post-submit-checker-policy/request-correction` `ProjectSetupRun` is only a setup ledger. Policy truth remains in the guide source snapshot, sufficiency report, submission artifact policy, effective @@ -83,6 +87,15 @@ checker derivation. That approval creates the effective project policy and compiled project pre-submit checker bundle before Workstream continues into post-submit setup. +The post-submit checker setup read returns only bounded operator summaries: +setup status, compiled checker names/severities, sufficiency status/counts, +effective policy counts, pre-submit checker names/count, and registered +post-submit checker catalog count. It does not return raw source text, local +paths, replayable refs, exact source hashes, or compiled policy body internals. +When `admin` or `project_manager` requests correction, Workstream clears the +unapproved compiled output, records safe correction provenance, and immediately +queues the same post-submit setup continuation for regeneration. + ## v0.1 Quality Gates ### Project Activation Gate @@ -91,11 +104,10 @@ A project cannot become active unless guide, immutable guide-source snapshot, passed or acknowledged guide sufficiency report, approved submission artifact policy, persisted effective project submission artifact policy hash, project pre-submit checker bundle hash, approved project post-submit checker policy, -review policy, revision policy, and payment policy are present. `WS-POL-002-02` -produces compiled post-submit setup output with exact source/effective/pre-submit -provenance, but activation remains blocked until the policy is approved through -the server-owned approval/correction path added in `WS-POL-002-03`. A task -cannot enter `READY` until it also locks the guide source +review policy, revision policy, and payment policy are present. Compiled +post-submit setup output carries exact source/effective/pre-submit provenance, +but activation remains blocked until the policy is approved through the +server-owned approval/correction API. A task cannot enter `READY` until it also locks the guide source snapshot id/hash, effective project submission artifact policy hash, and project pre-submit checker bundle hash. diff --git a/docs/product_first_user_flows.md b/docs/product_first_user_flows.md index 424d4cde8..e8f2a770d 100644 --- a/docs/product_first_user_flows.md +++ b/docs/product_first_user_flows.md @@ -15,15 +15,16 @@ The first user flows prove that Workstream can run real work from intake to acce 9. Admin or project_manager reviews and approves the derived submission artifact policy. 10. Workstream persists the effective project submission artifact policy hash. 11. Workstream compiles, persists, and locks the project `PreSubmitCheckerPolicy`. -12. Admin or project_manager enables post-submit checker policy. -13. Admin or project_manager enables review policy. -14. Admin or project_manager enables revision policy. -15. Admin or project_manager enables payment policy. -16. Project becomes active. +12. Workstream derives and compiles the project post-submit checker policy. +13. Admin or project_manager approves the compiled post-submit checker policy or requests correction. +14. Admin or project_manager enables review policy. +15. Admin or project_manager enables revision policy. +16. Admin or project_manager enables payment policy. +17. Project becomes active. Acceptance: -- Project cannot become active without guide, immutable guide source snapshot, passed or acknowledged guide sufficiency report for that immutable guide source snapshot, submission artifact policy, effective project submission artifact policy hash, project pre-submit checker bundle hash, post-submit checker policy, review policy, revision policy, and payment policy. +- Project cannot become active without guide, immutable guide source snapshot, passed or acknowledged guide sufficiency report for that immutable guide source snapshot, submission artifact policy, effective project submission artifact policy hash, project pre-submit checker bundle hash, approved post-submit checker policy, review policy, revision policy, and payment policy. - Normal setup starts from guide/source capture. Admins and project managers do not manually trigger sufficiency or derivation in the happy path. - Submission artifact policy is Workstream-derived and approved by `admin` or `project_manager`; project owners do not author or approve the machine policy schema directly. - This flow is the agent-derived setup path. If an admin or project_manager creates a manual sufficiency report for a snapshot, that snapshot continues through manual policy creation; agent derivation requires an agent-created sufficiency report for the same snapshot or a fresh guide-source snapshot. @@ -42,7 +43,7 @@ Acceptance: - Missing required fields block `SCREENING`. - Missing required fields block `READY`. -- Task shows project guide, required artifacts, generated project pre-submit checker policy summary, post-submit checker policy, review policy, revision policy, and payment policy. +- Task shows project guide, required artifacts, generated project pre-submit checker policy summary, operator-visible post-submit checker policy summary, review policy, revision policy, and payment policy. ## Flow 3: Worker Submits Work From dec79fbfea11dee2672495b1a92603c3a50e199c Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 14:51:32 +0100 Subject: [PATCH 02/14] Add WS-POL-002-03 review evidence --- .agent-loop/LOOP_STATE.md | 2 +- .../WS-POL-002-03-internal-review-evidence.md | 92 ++++++++++ .../reviews/WS-POL-002-03-pr-trust-bundle.md | 169 ++++++++++++++++++ 3 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md create mode 100644 .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md diff --git a/.agent-loop/LOOP_STATE.md b/.agent-loop/LOOP_STATE.md index b6213bea9..27c757225 100644 --- a/.agent-loop/LOOP_STATE.md +++ b/.agent-loop/LOOP_STATE.md @@ -12,7 +12,7 @@ - Last merged implementation SHA: `67fb3ca` - Last merge commit: `32af6a7` - Current gate: evidence packaging, trust bundle, PR publication, external - review, and human merge checkpoint. + review, and user review. - Next chunk: `WS-POL-002-04` remains inactive until `WS-POL-002-03` is merged by explicit human approval and memory is updated. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md new file mode 100644 index 000000000..f580332e2 --- /dev/null +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md @@ -0,0 +1,92 @@ +# Internal Review Evidence: WS-POL-002-03 + +## Chunk + +WS-POL-002-03 - Server-Owned Policy Approval And Visibility APIs + +open sub-agent sessions: none + +valid findings addressed: yes + +## Reviewed Revision + +Reviewed code SHA: ae7e0a1d9ec2804ec32a6b262197d685f137550a + +Reviewed at: 2026-07-11T13:49:15Z + +Reviewer run ids: senior-engineering-019f5133-8882, qa-test-019f5133-9349, security-auth-019f5133-a018, product-ops-019f5133-b385, architecture-019f5133-cc0e, docs-019f5133-d78d, security-auth-rerun-019f513f-0255, product-ops-rerun-019f513e-fcdf, reuse-dedup-019f513f-0938, test-delta-019f513f-116c, ci-integrity-019f513f-1ce8 + +## Reviewed Change + +Branch: `codex/ws-pol-002-03-post-submit-approval-visibility` + +Scope: + +- Adds operator-only setup visibility for generated project `PostSubmitCheckerPolicy` state. +- Adds server-owned approval and correction endpoints for generated post-submit checker policies. +- Keeps obsolete client-owned `post_submit_checker_policy` guide payloads rejected. +- Requires approved post-submit policy context to match the current guide, source snapshot, effective project policy, and compiled pre-submit checker. +- Records immutable approval provenance without accepting caller-provided approval notes. +- Clears unapproved generated output during correction and immediately requeues the existing setup continuation. +- Redacts raw source text, local paths, exact source hashes, source item refs, policy bodies, secrets, and credential-shaped values from setup visibility responses. +- Adds negative authorization coverage for worker, reviewer, finance, and auditor roles. +- Updates operator/product/data-model docs and active loop state for this chunk. + +## Reviewer Results + +These are Codex engineering-loop reviewer verdicts, not Workstream product +review decisions. Product review decisions remain `accept`, `needs_revision`, +and `reject`; internal reviewer agents report `PASS`, `PASS WITH LOW RISKS`, +`PASS AFTER FIXES`, or `FAIL` so process evidence stays separate from product +lifecycle records. + +| Reviewer | Result | Blocking findings | Notes | +|---|---:|---|---| +| senior engineering | PASS WITH LOW RISKS | None | Confirmed the service/repository boundary stayed narrow and no task runtime behavior was pulled into this chunk. | +| QA/test | PASS WITH LOW RISKS | None | Found ignored approval-note input; fixed by removing the field and keeping the approval body empty with `extra="forbid"`. | +| security/auth | PASS | None | Initial credential-shaped redaction concern was fixed and retested with `sk-` style redaction in correction metadata. | +| product/ops | PASS WITH LOW RISKS | None | Initial correction dead-end and visibility-summary concerns were fixed with automatic setup continuation and bounded derivation input summary. | +| architecture | PASS WITH LOW RISKS | None | Confirmed the server-owned setup path remains project-scoped and does not introduce runtime agent judgment or per-task checker generation. | +| docs | PASS WITH LOW RISKS | None | Found checklist drift around post-submit policy approval; fixed in the operator manual and product flow docs. | +| reuse/dedup | PASS WITH LOW RISKS | None | Found no blocking duplication; service helpers stayed local to the projects boundary. | +| test delta | PASS WITH LOW RISKS | None | Requested broader leakage assertions; fixed by asserting policy body, source refs, source hashes, and guide text are absent. | +| CI integrity | PASS WITH LOW RISKS | None | Confirmed no CI/test weakening; final project/auth and Alembic tests were rerun after fixes. | + +## Valid Findings Addressed + +- Removed caller-supplied approval notes from `PostSubmitCheckerPolicyApproval` so approval provenance is server-owned and no ignored input is accepted. +- Added credential-shape redaction for bounded setup summaries and correction metadata. +- Added automatic setup continuation enqueue after correction clears unapproved generated output. +- Added bounded `derivation_input_summary` so operators can see source/effective/pre-submit context without raw source material or policy bodies. +- Changed product wording from "task display" to "operator-visible post-submit checker policy summary". +- Expanded tests to assert no policy body, source item ref, source item hash, raw source hash, or guide text leaks in setup visibility responses. + +## Commands Run + +```bash +cd backend && .venv/bin/pytest tests/test_projects.py::test_post_submit_checker_policy_approval_uses_server_provenance tests/test_projects.py::test_post_submit_checker_policy_correction_clears_unapproved_output -q +cd backend && .venv/bin/pytest tests/test_projects.py -q -k "post_submit_checker_policy or post_submit_setup_visibility" +cd backend && .venv/bin/pytest tests/test_auth.py -q +cd backend && .venv/bin/pytest tests/test_alembic.py -q +cd backend && .venv/bin/pytest tests/test_projects.py tests/test_auth.py -q +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_markdown_links.py +git diff --check +``` + +Results: + +- Targeted approval/correction tests: 2 passed. +- Focused post-submit project setup slice: 9 passed, 224 deselected. +- Auth suite: 21 passed. +- Alembic suite: 6 passed. +- Final project/auth suite: 254 passed in 2825.49s. +- Stale wording scan: passed. +- Markdown link check: passed. +- Diff whitespace check: passed. + +## Remaining Risks + +- External GitHub Actions and CodeRabbit must run on the pushed PR head before human merge review. +- Project-scoped `project_manager` role grants remain future Workstream role-assignment work; this chunk keeps the current bootstrap authorization boundary and documents that limit. +- `WS-POL-002-04` still owns runtime hardening for locked post-submit policy execution and routing. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md new file mode 100644 index 000000000..ee31d2403 --- /dev/null +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md @@ -0,0 +1,169 @@ +# PR Trust Bundle: WS-POL-002-03 + +## Chunk + +`WS-POL-002-03` - Server-Owned Policy Approval And Visibility APIs + +## Reviewed Revision + +Reviewed code SHA: `ae7e0a1d9ec2804ec32a6b262197d685f137550a` + +Reviewed at: `2026-07-11T13:49:15Z` + +Internal review evidence: + +- `.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md` + +## Goal + +Expose generated post-submit checker setup state through safe APIs and replace +manual setup approval shortcuts with server-owned approval/correction actions. + +## Human-Approved Intent + +Post-submit setup mirrors the pre-submit separation: + +```text +Project guide/source material +-> setup-time derivation agent +-> trusted Workstream compiler +-> generated project PostSubmitCheckerPolicy +-> setup-authorized admin/project_manager approval or correction request +-> active guide can lock the approved policy +``` + +The agent derives constrained setup policy. Workstream owns approval, +correction, visibility, and activation checks. The agent still does not judge +worker submissions at runtime. + +## What Changed + +- Added setup visibility endpoint: + - `GET /api/v1/projects/{project_id}/guides/{guide_id}/post-submit-checker-policy/setup` +- Added server-owned approval endpoint: + - `POST /api/v1/projects/{project_id}/guides/{guide_id}/post-submit-checker-policy/approve` +- Added server-owned correction endpoint: + - `POST /api/v1/projects/{project_id}/guides/{guide_id}/post-submit-checker-policy/request-correction` +- Added safe setup summaries that expose IDs, lifecycle status, checker counts/names, policy hash, approval provenance, and bounded derivation input context. +- Kept raw source text, local paths, exact source hashes, source item refs, policy bodies, and credential-shaped strings out of setup visibility responses. +- Added row-locking and current-context validation before approval/correction. +- Made approval idempotent without rewriting existing approval provenance. +- Made correction clear unapproved generated output, delete the compiled policy row, preserve correction metadata, and requeue the existing setup continuation. +- Updated docs and loop state to reflect the new server-owned setup boundary. + +## Design Chosen + +Approval is a server-owned state transition, not a client patch: + +```text +compiled policy +-> lock guide and policy rows +-> validate guide/source/effective/pre-submit/setup-run context +-> mark policy approved with server actor/role/time provenance +-> return safe setup summary +``` + +Correction is also server-owned: + +```text +draft guide + unapproved compiled policy +-> lock context +-> clear setup output +-> delete unapproved compiled policy +-> store redacted correction metadata on setup run +-> enqueue setup continuation after commit +``` + +## Alternatives Rejected + +- Client-provided approval notes: rejected because they were not consumed by the domain model and could become misleading ignored input. +- Worker-visible policy bodies: rejected. Workers only need actionable checker results later in runtime flows. +- Manual guide payload policy fields: rejected. Generated setup output is the authoritative path. +- Project setup correction as a dead end: rejected. Correction now resumes the setup pipeline automatically. +- Runtime agent judgment: rejected. Runtime remains deterministic checker execution. + +## Scope Control + +This chunk stays inside project setup visibility and approval. It does not +change task runtime, checker runtime, frontend/demo work, payment, reputation, +blockchain settlement, reviewer decision records, or per-task checker policy +generation. + +## Acceptance Criteria Proof + +- Project setup APIs show generated post-submit policy status without database inspection. +- Guide create/update still rejects obsolete `post_submit_checker_policy` payload fields. +- Guide activation blocks unless the compiled post-submit policy is approved and matches the current guide/source/effective/pre-submit context. +- Approval provenance is server-owned, immutable on retry, and records actor id, role, timestamp, source snapshot id/hash, and compiled policy hash. +- Setup visibility does not leak internal policy body details, raw source material, local source refs, exact source hashes, or credential-shaped correction text. +- Worker, reviewer, finance, and auditor roles are denied on setup visibility, approval, and correction endpoints. +- Correction clears unapproved generated output and requeues setup continuation rather than leaving setup blocked forever. + +## Tests/Checks Run + +```bash +cd backend && .venv/bin/pytest tests/test_projects.py::test_post_submit_checker_policy_approval_uses_server_provenance tests/test_projects.py::test_post_submit_checker_policy_correction_clears_unapproved_output -q +cd backend && .venv/bin/pytest tests/test_projects.py -q -k "post_submit_checker_policy or post_submit_setup_visibility" +cd backend && .venv/bin/pytest tests/test_auth.py -q +cd backend && .venv/bin/pytest tests/test_alembic.py -q +cd backend && .venv/bin/pytest tests/test_projects.py tests/test_auth.py -q +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_markdown_links.py +git diff --check +``` + +Result summary: + +- Targeted approval/correction tests: 2 passed. +- Focused post-submit project setup slice: 9 passed. +- Auth suite: 21 passed. +- Alembic suite: 6 passed. +- Final project/auth suite: 254 passed. +- Stale wording scan: passed. +- Markdown link check: passed. +- Diff whitespace check: passed. + +## Reviewer Results + +These are Codex engineering-loop reviewer verdicts, not Workstream product +review decisions. Product review decisions remain `accept`, `needs_revision`, +and `reject`; internal reviewer agents report `PASS`, `PASS WITH LOW RISKS`, +`PASS AFTER FIXES`, or `FAIL` so process evidence stays separate from product +lifecycle records. + +| Reviewer | Result | Blocking findings | Notes | +|---|---:|---|---| +| senior engineering | PASS WITH LOW RISKS | None | Service/repository boundary stayed narrow. | +| QA/test | PASS WITH LOW RISKS | None | Approval-note issue fixed by removing the input field. | +| security/auth | PASS | None | Credential-shaped redaction and non-setup role denials covered. | +| product/ops | PASS WITH LOW RISKS | None | Correction continuation and operator summary gaps fixed. | +| architecture | PASS WITH LOW RISKS | None | No runtime agent judgment or per-task checker generation added. | +| docs | PASS WITH LOW RISKS | None | Operator manual and product flow aligned. | +| reuse/dedup | PASS WITH LOW RISKS | None | No blocking reuse issues. | +| test delta | PASS WITH LOW RISKS | None | Leak assertions broadened. | +| CI integrity | PASS WITH LOW RISKS | None | No CI/test weakening found. | + +## External Review + +GitHub Actions and CodeRabbit must rerun on the pushed PR head before human +merge review. + +## Remaining Risks + +- The current bootstrap authorization still treats global `admin` and + `project_manager` as setup-authorized; project-scoped role assignment remains + future Workstream role work. +- `WS-POL-002-04` still owns runtime hardening for locked post-submit policy + execution and routing. + +## Human Review Focus + +- Confirm there is one authoritative server-owned post-submit policy approval path. +- Confirm correction safely clears unapproved output and resumes setup. +- Confirm operator visibility is useful without leaking source/policy secrets. +- Confirm worker-facing APIs remain out of scope for setup internals. + +## Human Merge Ownership + +Only the user can approve and merge this PR. Codex must not merge it without +explicit user approval for this specific PR. From aa3325ab8b39681bbddfe77663915c7fdc01d08e Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 14:53:09 +0100 Subject: [PATCH 03/14] Update WS-POL-002-03 PR state --- .agent-loop/LOOP_STATE.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.agent-loop/LOOP_STATE.md b/.agent-loop/LOOP_STATE.md index 27c757225..55431ed31 100644 --- a/.agent-loop/LOOP_STATE.md +++ b/.agent-loop/LOOP_STATE.md @@ -7,12 +7,11 @@ - Active implementation chunk: `WS-POL-002-03` - Server-Owned Policy Approval And Visibility APIs - Branch: `codex/ws-pol-002-03-post-submit-approval-visibility` -- Status: `WS-POL-002-03` implemented and internally reviewed; evidence and PR - publication are in progress. +- Status: `WS-POL-002-03` implemented and internally reviewed; pull request + created at `https://github.com/Flow-Research/workstream/pull/90`. - Last merged implementation SHA: `67fb3ca` - Last merge commit: `32af6a7` -- Current gate: evidence packaging, trust bundle, PR publication, external - review, and user review. +- Current gate: external review, GitHub checks, and user review. - Next chunk: `WS-POL-002-04` remains inactive until `WS-POL-002-03` is merged by explicit human approval and memory is updated. From 19680969d267c339907bc507ec37b22c65665298 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 16:08:04 +0100 Subject: [PATCH 04/14] Rebind WS-POL-002-03 review evidence --- .../WS-POL-002-03-external-review-response.md | 37 +++++++++++++++++++ .../WS-POL-002-03-internal-review-evidence.md | 13 +++++-- .../reviews/WS-POL-002-03-pr-trust-bundle.md | 14 +++++-- 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md new file mode 100644 index 000000000..b0fd3978a --- /dev/null +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md @@ -0,0 +1,37 @@ +# External Review Response: WS-POL-002-03 + +## Comments Addressed + +- GitHub Actions Agent Gates and Backend both failed at the internal review + evidence gate on PR head `8414dbdffcbcec108f0e736a06e7bbc750eca18b`. + The failure was valid: `main` had been merged into the PR branch after the + original evidence was bound, so the reviewed SHA was stale. +- Rebound `WS-POL-002-03` internal review evidence and PR trust bundle to the + merged PR head before this evidence-only repair commit. + +## Comments Deferred + +- None. + +## Human Decisions Needed + +- None from external review at this point. + +## Commands Rerun + +```bash +gh run view 29157251423 --log-failed +gh run view 29157251426 --log-failed +python3 scripts/check_internal_review_evidence.py +python3 scripts/check_loop_memory_state.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_markdown_links.py +git diff --check +``` + +## Remaining Risks + +- CodeRabbit hit a review-limit warning on the latest pass and did not post + actionable review threads. A later `@coderabbitai review` may be needed when + review capacity resets. +- GitHub Actions must rerun on the pushed repair commit. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md index f580332e2..30458c637 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md @@ -10,9 +10,9 @@ valid findings addressed: yes ## Reviewed Revision -Reviewed code SHA: ae7e0a1d9ec2804ec32a6b262197d685f137550a +Reviewed code SHA: 8414dbdffcbcec108f0e736a06e7bbc750eca18b -Reviewed at: 2026-07-11T13:49:15Z +Reviewed at: 2026-07-11T15:07:06Z Reviewer run ids: senior-engineering-019f5133-8882, qa-test-019f5133-9349, security-auth-019f5133-a018, product-ops-019f5133-b385, architecture-019f5133-cc0e, docs-019f5133-d78d, security-auth-rerun-019f513f-0255, product-ops-rerun-019f513e-fcdf, reuse-dedup-019f513f-0938, test-delta-019f513f-116c, ci-integrity-019f513f-1ce8 @@ -85,8 +85,15 @@ Results: - Markdown link check: passed. - Diff whitespace check: passed. +Rebind note: + +- The PR branch was updated with current `main` after the original evidence was + recorded. CI correctly failed the stale reviewed-SHA gate because non-evidence + files from `main` appeared above the prior reviewed commit. This evidence now + binds to the merged PR head before the evidence-only repair commit. + ## Remaining Risks -- External GitHub Actions and CodeRabbit must run on the pushed PR head before human merge review. +- GitHub Actions and CodeRabbit must rerun on the pushed PR head before human merge review. - Project-scoped `project_manager` role grants remain future Workstream role-assignment work; this chunk keeps the current bootstrap authorization boundary and documents that limit. - `WS-POL-002-04` still owns runtime hardening for locked post-submit policy execution and routing. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md index ee31d2403..48e27205b 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md @@ -6,9 +6,9 @@ ## Reviewed Revision -Reviewed code SHA: `ae7e0a1d9ec2804ec32a6b262197d685f137550a` +Reviewed code SHA: `8414dbdffcbcec108f0e736a06e7bbc750eca18b` -Reviewed at: `2026-07-11T13:49:15Z` +Reviewed at: `2026-07-11T15:07:06Z` Internal review evidence: @@ -145,8 +145,14 @@ lifecycle records. ## External Review -GitHub Actions and CodeRabbit must rerun on the pushed PR head before human -merge review. +External review response: + +- `.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md` + +CodeRabbit did not post actionable review threads on the latest pass because +the review limit was reached. GitHub Actions failed only because the reviewed +SHA became stale after `main` was merged into the PR branch. The evidence was +rebound to the merged PR head and must rerun on the pushed repair commit. ## Remaining Risks From e42b9506815a2eef155230928e791d5a737a6155 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 16:29:41 +0100 Subject: [PATCH 05/14] Align WS-POL-002-03 review state --- .agent-loop/LOOP_STATE.md | 21 +++++++------------ .agent-loop/REVIEW_LOG.md | 7 +++++-- .agent-loop/WORK_QUEUE.md | 14 ++++++++----- .../CHUNK_MAP.md | 4 ++-- .../DECISIONS.md | 9 +++++--- .../DISCOVERY.md | 4 ++-- .../INTENT.md | 7 +++++-- .../PLAN.md | 2 +- .../RISKS.md | 2 +- .../STATUS.md | 4 ++-- ...UTH-001-01-adopt-authorization-baseline.md | 6 ++++-- ...WS-AUTH-001-12-project-mutation-cutover.md | 3 ++- .../WS-AUTH-001-16-evidence-live-proof.md | 6 +++--- ...001-PLAN-authorization-service-planning.md | 5 +++-- .../CHUNK_MAP.md | 6 +++--- .../STATUS.md | 19 +++++++---------- docs/operations_project_operating_manual.md | 11 ++++++---- docs/product_first_user_flows.md | 11 +++++----- 18 files changed, 76 insertions(+), 65 deletions(-) diff --git a/.agent-loop/LOOP_STATE.md b/.agent-loop/LOOP_STATE.md index 8045f0eea..2ca512570 100644 --- a/.agent-loop/LOOP_STATE.md +++ b/.agent-loop/LOOP_STATE.md @@ -14,20 +14,15 @@ - Current gate: external review, GitHub checks, and user review. - Next chunk: `WS-POL-002-04` remains inactive until `WS-POL-002-03` is merged by explicit human approval and memory is updated. -- Active initiative: `WS-AUTH-001` - Workstream Authorization Service -- Active planning chunk: `WS-AUTH-001-PLAN` -- Active implementation chunk: none -- Branch: `authorization-service` +- Checkpointed initiative: `WS-AUTH-001` - Workstream Authorization Service +- Checkpointed planning artifact: `WS-AUTH-001-PLAN` - Status: WS-AUTH-001 planning is internally reviewed and stopped at the L0 - human checkpoint. D1-D3 are approved; D4-D10 require explicit approval. -- Last merged implementation SHA: `67fb3ca` -- Last merge commit: `32af6a7` -- Current gate: explicit durable human approval of D4-D10. Planning evidence is - recorded at the WS-AUTH-001 internal review evidence path. -- Next chunk: `WS-AUTH-001-01` remains proposed until D4-D10 approval and a - separate implementation start signal. -- Paused initiative: `WS-POL-002`; chunk `WS-POL-002-03` must not start before - the relevant authorization foundation and an explicit resume signal. + human checkpoint. It is not the active implementation stream while PR #90 is + current. +- Current gate: explicit durable human approval of D4-D10 before any + authorization implementation chunk starts. +- Next authorization chunk: `WS-AUTH-001-01` remains proposed until D4-D10 + approval and a separate implementation start signal. ## Operating Rule diff --git a/.agent-loop/REVIEW_LOG.md b/.agent-loop/REVIEW_LOG.md index a4f32de59..07b02b505 100644 --- a/.agent-loop/REVIEW_LOG.md +++ b/.agent-loop/REVIEW_LOG.md @@ -3,7 +3,9 @@ ## WS-POL-002-03 Status: implemented and internally reviewed on branch -`codex/ws-pol-002-03-post-submit-approval-visibility`; PR publication pending. +`codex/ws-pol-002-03-post-submit-approval-visibility`; pull request #90 is +current with local CodeRabbit-response fixes complete and external checks +pending for the next pushed head. Required reviewer tracks: @@ -17,7 +19,8 @@ Required reviewer tracks: - reuse/dedup - test delta -Result: PASS after fixes; external review pending. +Result: PASS after fixes locally; external review and GitHub checks must rerun +after the next push. Scope: server-owned post-submit checker policy setup visibility, approval, and correction APIs; safe operator summaries; immutable approval provenance; and diff --git a/.agent-loop/WORK_QUEUE.md b/.agent-loop/WORK_QUEUE.md index 0c2edb71e..bf317a2a7 100644 --- a/.agent-loop/WORK_QUEUE.md +++ b/.agent-loop/WORK_QUEUE.md @@ -4,16 +4,20 @@ | Chunk | Title | Risk | Status | |---|---|---:|---| -| `WS-AUTH-001-PLAN` | Authorization Service Planning | L0 | Internal review passed; explicit D4-D10 human approval pending | +| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | Pull request #90 current; local CodeRabbit fixes complete; push and external checks pending | ## Planned Next | Chunk | Title | Risk | Status | |---|---|---:|---| -| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | Implemented; internal review complete; PR publication pending | | `WS-POL-002-04` | Locked Runtime Execution And Routing Hardening | L1 | Inactive until explicit user start after `WS-POL-002-03` merge | | `WS-AUTH-001-01` | Adopt Authorization Baseline And Repository Contracts | L1 | Proposed after D4-D10 approval and explicit start | -| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | Paused behind WS-AUTH-001 and explicit resume | + +## Human Checkpoints + +| Chunk | Title | Risk | Status | +|---|---|---:|---| +| `WS-AUTH-001-PLAN` | Authorization Service Planning | L0 | Stopped at human checkpoint; explicit D4-D10 approval required before implementation | ## Completed @@ -47,8 +51,8 @@ Do not start `WS-POL-002-04` until `WS-POL-002-03` is externally reviewed, merged by explicit human approval, and followed by memory update. Stop at the WS-AUTH-001 planning human checkpoint. Do not activate -`WS-AUTH-001-01` before explicit D4-D10 approval and a separate start signal; -do not resume `WS-POL-002-03` while auth has priority. +`WS-AUTH-001-01` before explicit D4-D10 approval and a separate start signal. +Future WS-POL work after PR #90 also requires a separate start signal. ## Blocked diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md index 4014e7cf8..4595bd4ef 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md @@ -65,8 +65,8 @@ WS-AUTH-001-PLAN - Chunks 11-15 migrate bounded complete product/system surfaces. - Chunk 16 proves the complete initiative; it does not backfill missing audit or idempotency evidence. -- `WS-POL-002-03` remains paused until the relevant project authorization - cutover is complete and the user explicitly resumes it. +- `WS-POL-002-03` later resumed by explicit user start and is tracked in PR #90. + Future WS-POL chunks remain inactive until their own explicit start signals. ## Stop condition diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md index 6edac19a3..c3fc561eb 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md @@ -17,12 +17,15 @@ specification's `/v1` examples will be reconciled during the baseline-adoption chunk. Workstream will not expose two versioned route trees as permanent aliases. -## D3: Prioritize auth before WS-POL-002-03 +## D3: Prioritize auth before further WS-POL expansion Status: accepted by the user on 2026-07-11. -`WS-POL-002` is paused after merged chunk 02. New post-submit approval APIs must -not be built on authority rules that have been declared obsolete. +`WS-POL-002` was paused after merged chunk 02 when this plan was written. +`WS-POL-002-03` later resumed by explicit user start and is tracked in PR #90. +Future WS-POL chunks remain inactive until their own explicit start signals and +must account for the authorization direction before changing protected +surfaces. ## L0 human approval boundary diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md index 67894ea9f..8777d128d 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md @@ -128,13 +128,13 @@ requires explicit review in the token-verifier chunk. | Stale queued authority | Jobs may carry authority that has been revoked. | Re-resolve actor/grant state before actor-attributed commits. | | Claim/PII leakage | Current registry persists sanitized claim snapshots and role observations. | Minimize persisted identity data; never persist raw token/JWKS material. | | Namespace drift | New specs say `/v1`; repo uses `/api/v1`. | Record `/api/v1` as the adopted repository override and update generated/reference artifacts coherently. | -| Current initiative interruption | `WS-POL-002` is incomplete after chunk 02. | Mark it paused, do not implement chunk 03 until auth foundation is ready. | +| Current initiative interruption | `WS-POL-002` was incomplete after chunk 02 when this plan was written. | Historical: chunk 03 later resumed by explicit user start and is tracked in PR #90; future chunks still need explicit starts. | ## Unknowns/questions for human No blocking product questions remain for planning. The user explicitly adopted `WS-AUTH-001`, retained `/api/v1`, and prioritized auth before -`WS-POL-002-03`. +future WS-POL chunks after `WS-POL-002-03`. Production deployment inputs remain externally supplied: diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md index 7b5c58614..fee5680af 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md @@ -118,7 +118,9 @@ namespace and remains canonical. - Existing task lifecycle behavior except the explicit, audited release of an exclusive assignment when its actor/link/project authority is invalidated. - CI, test, documentation, and internal-review gates. -- `WS-POL-002-03` remains paused until the authorization foundation is ready. +- `WS-POL-002-03` later resumed by explicit user start and is tracked in PR #90. + Future WS-POL chunks still require explicit starts after their predecessors + merge and memory is updated. ## How this will be proven @@ -139,7 +141,8 @@ Resolved: - `WS-AUTH-001` is authoritative and supersedes the token-role bootstrap. - `/api/v1` remains the canonical API namespace. -- `WS-AUTH-001` is prioritized before `WS-POL-002-03`. +- `WS-AUTH-001` was prioritized before future WS-POL expansion; `WS-POL-002-03` + is now an active exception tracked in PR #90 after explicit user start. Pending before `WS-AUTH-001-01` activation: diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md index 8e5c4723a..497cc39c1 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md @@ -55,7 +55,7 @@ its old token-role authorization. No command accepts token role or local grant as alternate sufficient proof. Project configuration moves first because it is required to create project -grants and later resume `WS-POL-002-03`. Task/submission/checker access follows +grants and safely continue future WS-POL work after PR #90. Task/submission/checker access follows after exact-project contributor grants and resource loaders exist. Chunk 06 preserves task claim/start/submission operability through an explicitly diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md index 16f6e999f..c72037788 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md @@ -28,7 +28,7 @@ | A11 | API namespace forks | Client and documentation drift | Adopt `/api/v1` only and update references together | Route/OpenAPI and stale-reference scan | | A12 | Existing intake regresses | Project/task/checker pipeline stops | Run full current suite and API drill after actor migration and each cutover surface | Existing backend suite and live drill | | A13 | Auth initiative becomes one oversized PR | Review failure and hidden coupling | Sixteen bounded implementation chunks, one active at a time | Circuit-breaker and PR-size evidence | -| A14 | WS-POL work resumes on obsolete auth | Rework and inconsistent authority | Keep WS-POL-002-03 paused in durable loop state | Loop-memory gate | +| A14 | Future WS-POL work resumes on obsolete auth | Rework and inconsistent authority | Keep future WS-POL chunks inactive until explicit starts and authorization impact is reviewed | Loop-memory gate | | A15 | Authority mutation ships before durable evidence | Missing provenance cannot be reconstructed | Introduce correlation/idempotency/shared audit with canonical actor persistence | Atomic state+idempotency+event tests in every authority chunk | | A16 | Identity-link revocation strands final administrator | Administrative lockout despite active grant row | Apply AuthorityControl lock to link revoke plus grant/profile changes | Mixed concurrent link/grant/profile final-admin tests | | A17 | Canonical actor migration deletes typed-profile workflow eligibility before task/submission cutover | An intermediate merged release cannot claim, start, or submit work | Bounded non-authoritative workflow-eligibility adapter in chunk 06; remove task consumers in 13 and final consumer plus adapter in 14 | Full suite/API drill after chunks 06, 13, 14, and scanner proof in 15 | diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md index 96f019683..118c69eff 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md @@ -6,7 +6,7 @@ Planning and all required internal reviewer tracks passed after repair. The initiative is stopped at the L0 human checkpoint: D1-D3 are approved; D4-D10 require explicit durable approval before implementation activation. -## Active planning chunk +## Checkpointed planning artifact `WS-AUTH-001-PLAN` @@ -50,7 +50,7 @@ implementation start signal. Internal review evidence is recorded at `reviews/WS-AUTH-001-PLAN-internal-review-evidence.md` and binds reviewed SHA -`5739e1d6fc8df0fa620bd007c45e370530ac8d12`. +`54912769b8a066977d6dc62ec885b94a5ee05029`. Production issuer configuration and legacy non-test actor classification are future implementation/live-proof inputs and are tracked explicitly in diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md index 719b8187f..c0bf7f288 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md @@ -116,9 +116,11 @@ adding permanent /v1 aliases `docs/reference_specs/README.md` records their hashes/status and the `/api/v1` override; canonical reconciled text lives separately in `docs/spec_authorization_service.md`. -- `WS-POL-002-03` is durably paused behind the auth initiative. +- Future WS-POL chunks remain gated by explicit start signals and authorization + impact review. - Roadmap status names WS-AUTH-001 as current priority, records POL-002 chunks - 01/02 merged and 03 paused, and defers review implementation until auth proof. + 01/02 merged and 03 handled separately in PR #90, and defers review + implementation until auth proof. - Canonical vocabulary distinguishes `worker` as a task-lifecycle persona and attribution term from `submitter` as the persisted exact-project grant. - Every current operational override/repair command is inventoried and assigned diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md index a4eed9c3e..616a89745 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md @@ -13,7 +13,8 @@ provenance. ## Why this chunk exists This completes project authorization and unblocks later resumption of -`WS-POL-002-03` without implementing that paused chunk. +the project setup approval surface without implementing unrelated WS-POL +runtime behavior. ## Approved plan reference diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md index 006d15939..d8d54e122 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md @@ -62,7 +62,7 @@ review/contribution/compensation implementation production credentials or private keys in fixtures/evidence direct database bootstrap or grant edits in live proof loosening issuer, scope, permission, or resource guards -starting WS-POL-002-03 automatically +starting future WS-POL chunks automatically ``` ## Acceptance criteria @@ -100,8 +100,8 @@ starting WS-POL-002-03 automatically production dependency change requires separately recorded explicit human approval before modification. - No obsolete token-role authorization remains in runtime code. -- Initiative memory records proof and leaves `WS-POL-002-03` inactive until an - explicit user resume signal. +- Initiative memory records proof and leaves future WS-POL chunks inactive + until explicit user start signals. ## Verification commands diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md index 66986acb8..53863faae 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md @@ -66,7 +66,8 @@ review, contribution, compensation, frontend, or WS-POL implementation - Every implementation chunk has allowed files, exclusions, acceptance criteria, verification, reviewers, human focus, and stop conditions. - The plan preserves `/api/v1`, prevents dual authority, handles legacy actor - classification fail-closed, and pauses `WS-POL-002-03`. + classification fail-closed, and records authorization priority for future + WS-POL chunks. - Required internal plan reviews pass and all valid findings are resolved or documented. - The plan distinguishes approved L0 direction from proposed L0 decisions and @@ -99,7 +100,7 @@ git diff --check ## Human review focus Review the authority precedence, migration safety, chunk size/order, `/api/v1` -decision, WS-POL pause, and proof strategy. +decision, WS-POL follow-up gating, and proof strategy. ## Stop conditions diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md index b5bd629c9..16a2fccfa 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md @@ -13,7 +13,6 @@ reviewed, merged by explicit human approval, and followed by a memory update. | `WS-POL-002-01` | Post-Submit Compiler Contract | L1 | Merged | | `WS-POL-002-02` | Post-Submit Derivation Agent And Resumable Setup Integration | L1 | Merged | | `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | In review | -| `WS-POL-002-03` | Server-Owned Policy Approval And Visibility APIs | L1 | Paused behind WS-AUTH-001 and explicit resume | | `WS-POL-002-04` | Locked Runtime Execution And Routing Hardening | L1 | Proposed | | `WS-POL-002-05` | Terminal Benchmark Post-Submit Live API Proof | L1 | Proposed | @@ -33,5 +32,6 @@ After each implementation chunk is reviewed, externally checked, and merged by explicit human approval, perform the memory update before starting the next chunk. -The initiative is currently paused after chunk 02 by explicit human priority -for `WS-AUTH-001`. Do not start chunk 03 automatically. +`WS-POL-002-03` is current in PR #90 after an explicit user start. Do not start +`WS-POL-002-04` automatically after PR #90; it requires merge, memory update, +and a separate explicit start signal. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md index cfb066b09..4c51258cb 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md @@ -5,11 +5,6 @@ Planning completed and merged through PR #85 as `3fc1a688743f13476d6092078d40792592823d27`. -The initiative is paused after chunk 02 by the user's 2026-07-11 decision to -prioritize `WS-AUTH-001`. No later chunk may start until the relevant -authorization foundation exists and the user explicitly resumes this -initiative. - `WS-POL-002-01` merged through PR #87 as `ed52c21` on 2026-07-09. It implemented the version-stamped trusted post-submit compiler contract, default-checker snapshot validation, canonical policy hashing, and tests around @@ -22,16 +17,17 @@ contributor submission handoff to the pre-review gate, and repair-only `/finalize` semantics. `WS-POL-002-03` is implemented and internally reviewed on branch -`codex/ws-pol-002-03-post-submit-approval-visibility`; PR publication and -external review are pending. +`codex/ws-pol-002-03-post-submit-approval-visibility`; pull request #90 is +current with local CodeRabbit-response fixes complete; push and external checks +are pending. ## Active Planning Chunk -`WS-POL-002-03` - Server-Owned Policy Approval And Visibility APIs +None. ## Active Implementation Chunk -None. +`WS-POL-002-03` - Server-Owned Policy Approval And Visibility APIs ## Current Implementation Branch @@ -44,8 +40,7 @@ None. | `WS-POL-002-PLAN` | Merged | `codex/ws-pol-002-post-submit-checker-planning` | #85 | Defines intent, discovery, design, risks, decisions, and implementation chunks. | | `WS-POL-002-01` | Merged | `codex/ws-pol-002-01-post-submit-compiler` | #87 | Post-Submit Compiler Contract; merged as `ed52c21`. | | `WS-POL-002-02` | Merged | `codex/ws-pol-002-02-post-submit-derivation` | #88 | Post-submit derivation agent and resumable setup integration; merged as `32af6a7`. | -| `WS-POL-002-03` | In review | `codex/ws-pol-002-03-post-submit-approval-visibility` | - | Server-owned approval and setup visibility APIs for compiled post-submit policies. | -| `WS-POL-002-03` | Paused | - | - | Server-owned approval and setup visibility APIs; paused behind WS-AUTH-001 and explicit resume. | +| `WS-POL-002-03` | In review | `codex/ws-pol-002-03-post-submit-approval-visibility` | #90 | Server-owned approval and setup visibility APIs for compiled post-submit policies. | | `WS-POL-002-04` | Proposed | - | - | Runtime hardening for locked post-submit policy execution and routing. | | `WS-POL-002-05` | Proposed | - | - | Terminal Benchmark-style live API proof and report. | @@ -53,4 +48,4 @@ None. | Blocker | Owner | Next action | |---|---|---| -| `WS-AUTH-001` priority | Authorization foundation must precede new setup approval APIs | Complete relevant auth cutover, then require explicit user resume | +| none | none | none | diff --git a/docs/operations_project_operating_manual.md b/docs/operations_project_operating_manual.md index f5c88787e..990e9126b 100644 --- a/docs/operations_project_operating_manual.md +++ b/docs/operations_project_operating_manual.md @@ -42,7 +42,7 @@ Before releasing tasks: - post-submit checker derivation runs after submission artifact policy approval - generated project post-submit checker policy compiled, or unsupported checker gaps resolved - compiled project post-submit checker policy attached with source/effective/pre-submit provenance -- compiled project post-submit checker policy approved by `admin` or `project_manager`, or correction requested +- compiled project post-submit checker policy approved by `admin` or `project_manager`; a correction request is a blocked setup state that returns to regeneration - review policy attached - revision policy attached - payment policy attached @@ -93,8 +93,10 @@ effective policy counts, pre-submit checker names/count, and registered post-submit checker catalog count. It does not return raw source text, local paths, replayable refs, exact source hashes, or compiled policy body internals. When `admin` or `project_manager` requests correction, Workstream clears the -unapproved compiled output, records safe correction provenance, and immediately -queues the same post-submit setup continuation for regeneration. +unapproved compiled output, records safe correction provenance, immediately +queues the same post-submit setup continuation for regeneration, and keeps +activation blocked until the regenerated policy is approved through the +approval endpoint. ## v0.1 Quality Gates @@ -107,7 +109,8 @@ pre-submit checker bundle hash, approved project post-submit checker policy, review policy, revision policy, and payment policy are present. Compiled post-submit setup output carries exact source/effective/pre-submit provenance, but activation remains blocked until the policy is approved through the -server-owned approval/correction API. A task cannot enter `READY` until it also locks the guide source +server-owned approval endpoint. A correction request only requeues regeneration; +it does not satisfy activation. A task cannot enter `READY` until it also locks the guide source snapshot id/hash, effective project submission artifact policy hash, and project pre-submit checker bundle hash. diff --git a/docs/product_first_user_flows.md b/docs/product_first_user_flows.md index e8f2a770d..479c9cfc2 100644 --- a/docs/product_first_user_flows.md +++ b/docs/product_first_user_flows.md @@ -16,11 +16,12 @@ The first user flows prove that Workstream can run real work from intake to acce 10. Workstream persists the effective project submission artifact policy hash. 11. Workstream compiles, persists, and locks the project `PreSubmitCheckerPolicy`. 12. Workstream derives and compiles the project post-submit checker policy. -13. Admin or project_manager approves the compiled post-submit checker policy or requests correction. -14. Admin or project_manager enables review policy. -15. Admin or project_manager enables revision policy. -16. Admin or project_manager enables payment policy. -17. Project becomes active. +13. Admin or project_manager approves the compiled post-submit checker policy. +14. If admin or project_manager requests correction instead, Workstream clears unapproved output and returns to post-submit derivation; setup does not continue toward activation. +15. Admin or project_manager enables review policy. +16. Admin or project_manager enables revision policy. +17. Admin or project_manager enables payment policy. +18. Project becomes active. Acceptance: From 144eba131ca6b9eac8fed37ee011d69627e063e7 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 16:57:29 +0100 Subject: [PATCH 06/14] Rebind WS-POL-002-03 review evidence --- .../STATUS.md | 2 +- ...-AUTH-001-PLAN-internal-review-evidence.md | 14 +++++++--- .../WS-POL-002-03-external-review-response.md | 17 ++++++++--- .../WS-POL-002-03-internal-review-evidence.md | 28 +++++++++++++++---- .../reviews/WS-POL-002-03-pr-trust-bundle.md | 17 +++++++---- 5 files changed, 58 insertions(+), 20 deletions(-) diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md index 118c69eff..32859f690 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md @@ -50,7 +50,7 @@ implementation start signal. Internal review evidence is recorded at `reviews/WS-AUTH-001-PLAN-internal-review-evidence.md` and binds reviewed SHA -`54912769b8a066977d6dc62ec885b94a5ee05029`. +`e42b9506815a2eef155230928e791d5a737a6155`. Production issuer configuration and legacy non-test actor classification are future implementation/live-proof inputs and are tracked explicitly in diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md index 59fce435c..d6609f0f4 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md @@ -10,9 +10,9 @@ valid findings addressed: yes ## Reviewed Revision -Reviewed code SHA: 5739e1d6fc8df0fa620bd007c45e370530ac8d12 +Reviewed code SHA: e42b9506815a2eef155230928e791d5a737a6155 -Reviewed at: 2026-07-11T14:08:40Z +Reviewed at: 2026-07-11T15:51:10Z Reviewer run IDs: senior-engineering=/root/pdf_attr_engineering_review; QA/test=/root/pdf_attr_quality_review; security/auth=/root/pdf_attr_ci_docs_security_review; product/ops=/root/pdf_attr_quality_review; architecture=/root/pdf_attr_engineering_review; docs=/root/pdf_attr_ci_docs_security_review; CI-integrity=/root/pdf_attr_ci_docs_security_review; reuse/dedup=/root/pdf_attr_engineering_review; test-delta=/root/pdf_attr_quality_review @@ -34,9 +34,14 @@ Scope: - Preserved intermediate-release intake operability and revision obligations, assigned every temporary compatibility consumer and deletion owner, and prohibited test/CI/dependency bypasses. -- Paused `WS-POL-002-03` and left every implementation chunk inactive. +- At planning time, paused `WS-POL-002-03` and left every implementation chunk + inactive; `WS-POL-002-03` later resumed by explicit user start in PR #90. - Recorded D1-D3 as user-approved L0 direction and D4-D10 as an explicit human approval gate before `WS-AUTH-001-01` activation. +- Reconciled PR #90 loop-state wording across WS-AUTH artifacts so historical + pause language does not remain an active blocker for the already-started + `WS-POL-002-03` chunk. Related wording touched `WS-AUTH-001-01`, + `WS-AUTH-001-12`, `WS-AUTH-001-16`, and `WS-AUTH-001-PLAN` records. ## Reviewer Results @@ -116,4 +121,5 @@ Results: No implementation chunk is active. Do not activate `WS-AUTH-001-01` without explicit human approval of D4-D10 and a separate implementation start signal. -Do not resume `WS-POL-002-03` while authorization remains the priority. +Do not start future WS-POL chunks without explicit user start and authorization +impact review. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md index b0fd3978a..6b9269c5d 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md @@ -8,6 +8,15 @@ original evidence was bound, so the reviewed SHA was stale. - Rebound `WS-POL-002-03` internal review evidence and PR trust bundle to the merged PR head before this evidence-only repair commit. +- CodeRabbit found stale/conflicting lifecycle state across `LOOP_STATE.md`, + `WORK_QUEUE.md`, `REVIEW_LOG.md`, WS-POL-002 status/chunk-map artifacts, and + product/operator docs. +- Fixed the valid lifecycle-state comments by representing PR #90 as the current + `WS-POL-002-03` review chunk, removing duplicate or stale paused rows, and + marking future WS-POL work as separately gated. +- Fixed the valid correction-flow comment by stating that correction requests + block activation, clear unapproved output, requeue regeneration, and do not + satisfy the approval gate. ## Comments Deferred @@ -31,7 +40,7 @@ git diff --check ## Remaining Risks -- CodeRabbit hit a review-limit warning on the latest pass and did not post - actionable review threads. A later `@coderabbitai review` may be needed when - review capacity resets. -- GitHub Actions must rerun on the pushed repair commit. +- CodeRabbit and GitHub Actions passed on PR head `19680969d267c339907bc507ec37b22c65665298`. +- The current CodeRabbit-response fixes are bound to non-evidence commit + `e42b9506815a2eef155230928e791d5a737a6155` and must be pushed and checked + again before merge. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md index 30458c637..4d7e5688a 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md @@ -10,9 +10,9 @@ valid findings addressed: yes ## Reviewed Revision -Reviewed code SHA: 8414dbdffcbcec108f0e736a06e7bbc750eca18b +Reviewed code SHA: e42b9506815a2eef155230928e791d5a737a6155 -Reviewed at: 2026-07-11T15:07:06Z +Reviewed at: 2026-07-11T15:51:10Z Reviewer run ids: senior-engineering-019f5133-8882, qa-test-019f5133-9349, security-auth-019f5133-a018, product-ops-019f5133-b385, architecture-019f5133-cc0e, docs-019f5133-d78d, security-auth-rerun-019f513f-0255, product-ops-rerun-019f513e-fcdf, reuse-dedup-019f513f-0938, test-delta-019f513f-116c, ci-integrity-019f513f-1ce8 @@ -31,6 +31,11 @@ Scope: - Redacts raw source text, local paths, exact source hashes, source item refs, policy bodies, secrets, and credential-shaped values from setup visibility responses. - Adds negative authorization coverage for worker, reviewer, finance, and auditor roles. - Updates operator/product/data-model docs and active loop state for this chunk. +- Reconciles CodeRabbit-discovered lifecycle drift across WS-POL-002 and + WS-AUTH-001 artifacts so `WS-POL-002-03` is the current PR #90 review chunk + and future WS-POL chunks remain separately gated. Related lifecycle wording + touched `WS-AUTH-001-01`, `WS-AUTH-001-12`, `WS-AUTH-001-16`, and + `WS-AUTH-001-PLAN` records. ## Reviewer Results @@ -60,6 +65,13 @@ lifecycle records. - Added bounded `derivation_input_summary` so operators can see source/effective/pre-submit context without raw source material or policy bodies. - Changed product wording from "task display" to "operator-visible post-submit checker policy summary". - Expanded tests to assert no policy body, source item ref, source item hash, raw source hash, or guide text leaks in setup visibility responses. +- Addressed CodeRabbit feedback that correction requests could be read as an + activation alternative; product and operator docs now state correction blocks + activation, clears unapproved output, and returns to regeneration. +- Addressed CodeRabbit feedback that loop artifacts had conflicting + `WS-POL-002-03` lifecycle states; PR #90 is now represented as the active + user-review chunk, while `WS-POL-002-04` and future WS-POL work remain + inactive until explicit starts. ## Commands Run @@ -71,6 +83,7 @@ cd backend && .venv/bin/pytest tests/test_alembic.py -q cd backend && .venv/bin/pytest tests/test_projects.py tests/test_auth.py -q python3 scripts/check_stale_workstream_wording.py python3 scripts/check_markdown_links.py +python3 scripts/check_loop_memory_state.py git diff --check ``` @@ -83,17 +96,22 @@ Results: - Final project/auth suite: 254 passed in 2825.49s. - Stale wording scan: passed. - Markdown link check: passed. +- Loop memory state check: passed. - Diff whitespace check: passed. Rebind note: - The PR branch was updated with current `main` after the original evidence was recorded. CI correctly failed the stale reviewed-SHA gate because non-evidence - files from `main` appeared above the prior reviewed commit. This evidence now - binds to the merged PR head before the evidence-only repair commit. + files from `main` appeared above the prior reviewed commit. +- A later CodeRabbit pass found lifecycle-state drift between WS-POL and WS-AUTH + loop artifacts. This evidence now binds to the non-evidence commit that + reconciles those artifacts before this evidence-only rebind commit. ## Remaining Risks -- GitHub Actions and CodeRabbit must rerun on the pushed PR head before human merge review. +- GitHub Actions and CodeRabbit passed on PR head + `19680969d267c339907bc507ec37b22c65665298` before the local + CodeRabbit-response fixes. They must rerun after these fixes are pushed. - Project-scoped `project_manager` role grants remain future Workstream role-assignment work; this chunk keeps the current bootstrap authorization boundary and documents that limit. - `WS-POL-002-04` still owns runtime hardening for locked post-submit policy execution and routing. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md index 48e27205b..5d5caf4fa 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md @@ -6,9 +6,9 @@ ## Reviewed Revision -Reviewed code SHA: `8414dbdffcbcec108f0e736a06e7bbc750eca18b` +Reviewed code SHA: `e42b9506815a2eef155230928e791d5a737a6155` -Reviewed at: `2026-07-11T15:07:06Z` +Reviewed at: `2026-07-11T15:51:10Z` Internal review evidence: @@ -50,6 +50,9 @@ worker submissions at runtime. - Made approval idempotent without rewriting existing approval provenance. - Made correction clear unapproved generated output, delete the compiled policy row, preserve correction metadata, and requeue the existing setup continuation. - Updated docs and loop state to reflect the new server-owned setup boundary. +- Reconciled CodeRabbit-discovered loop-state drift so PR #90 is the current + `WS-POL-002-03` review chunk, while `WS-POL-002-04` and future WS-POL chunks + remain inactive until explicit starts. ## Design Chosen @@ -149,10 +152,12 @@ External review response: - `.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md` -CodeRabbit did not post actionable review threads on the latest pass because -the review limit was reached. GitHub Actions failed only because the reviewed -SHA became stale after `main` was merged into the PR branch. The evidence was -rebound to the merged PR head and must rerun on the pushed repair commit. +CodeRabbit and GitHub Actions passed on PR head +`19680969d267c339907bc507ec37b22c65665298`. GitHub Actions had previously +failed only because the reviewed SHA became stale after `main` was merged into +the PR branch. The current review-response fixes are bound to non-evidence +commit `e42b9506815a2eef155230928e791d5a737a6155` and must be pushed and +checked again before merge. ## Remaining Risks From 5a04d7934423e815a2d1a03d29661d5cd6786d64 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 17:12:35 +0100 Subject: [PATCH 07/14] Rebind WS-POL-002-03 evidence after main merge --- .../WS-AUTH-001-workstream-authorization-service/STATUS.md | 2 +- .../reviews/WS-AUTH-001-PLAN-internal-review-evidence.md | 4 ++-- .../reviews/WS-POL-002-03-external-review-response.md | 2 +- .../reviews/WS-POL-002-03-internal-review-evidence.md | 7 +++++-- .../reviews/WS-POL-002-03-pr-trust-bundle.md | 6 +++--- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md index 099e63dc5..a86796846 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md @@ -54,7 +54,7 @@ implementation start signal. Internal review evidence is recorded at `reviews/WS-AUTH-001-PLAN-internal-review-evidence.md` and binds reviewed SHA -`7aed967da8783eb78e13805d4de00efadc8d0391`. +`6966c868b9a5f931b91f900ec754044cb61fabba`. Production issuer configuration and legacy non-test actor classification are future implementation/live-proof inputs and are tracked explicitly in diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md index d6609f0f4..3ed67fc71 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md @@ -10,9 +10,9 @@ valid findings addressed: yes ## Reviewed Revision -Reviewed code SHA: e42b9506815a2eef155230928e791d5a737a6155 +Reviewed code SHA: 6966c868b9a5f931b91f900ec754044cb61fabba -Reviewed at: 2026-07-11T15:51:10Z +Reviewed at: 2026-07-11T16:10:55Z Reviewer run IDs: senior-engineering=/root/pdf_attr_engineering_review; QA/test=/root/pdf_attr_quality_review; security/auth=/root/pdf_attr_ci_docs_security_review; product/ops=/root/pdf_attr_quality_review; architecture=/root/pdf_attr_engineering_review; docs=/root/pdf_attr_ci_docs_security_review; CI-integrity=/root/pdf_attr_ci_docs_security_review; reuse/dedup=/root/pdf_attr_engineering_review; test-delta=/root/pdf_attr_quality_review diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md index 6b9269c5d..7c3dcb96b 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-external-review-response.md @@ -42,5 +42,5 @@ git diff --check - CodeRabbit and GitHub Actions passed on PR head `19680969d267c339907bc507ec37b22c65665298`. - The current CodeRabbit-response fixes are bound to non-evidence commit - `e42b9506815a2eef155230928e791d5a737a6155` and must be pushed and checked + `6966c868b9a5f931b91f900ec754044cb61fabba` and must be pushed and checked again before merge. diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md index 4d7e5688a..0727efdd2 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-internal-review-evidence.md @@ -10,9 +10,9 @@ valid findings addressed: yes ## Reviewed Revision -Reviewed code SHA: e42b9506815a2eef155230928e791d5a737a6155 +Reviewed code SHA: 6966c868b9a5f931b91f900ec754044cb61fabba -Reviewed at: 2026-07-11T15:51:10Z +Reviewed at: 2026-07-11T16:10:55Z Reviewer run ids: senior-engineering-019f5133-8882, qa-test-019f5133-9349, security-auth-019f5133-a018, product-ops-019f5133-b385, architecture-019f5133-cc0e, docs-019f5133-d78d, security-auth-rerun-019f513f-0255, product-ops-rerun-019f513e-fcdf, reuse-dedup-019f513f-0938, test-delta-019f513f-116c, ci-integrity-019f513f-1ce8 @@ -107,6 +107,9 @@ Rebind note: - A later CodeRabbit pass found lifecycle-state drift between WS-POL and WS-AUTH loop artifacts. This evidence now binds to the non-evidence commit that reconciles those artifacts before this evidence-only rebind commit. +- Current `main` was merged again after WS-AUTH-001 post-merge memory landed; + this evidence now binds to that merge resolution before this evidence-only + rebind commit. ## Remaining Risks diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md index 5d5caf4fa..fe221d046 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-03-pr-trust-bundle.md @@ -6,9 +6,9 @@ ## Reviewed Revision -Reviewed code SHA: `e42b9506815a2eef155230928e791d5a737a6155` +Reviewed code SHA: `6966c868b9a5f931b91f900ec754044cb61fabba` -Reviewed at: `2026-07-11T15:51:10Z` +Reviewed at: `2026-07-11T16:10:55Z` Internal review evidence: @@ -156,7 +156,7 @@ CodeRabbit and GitHub Actions passed on PR head `19680969d267c339907bc507ec37b22c65665298`. GitHub Actions had previously failed only because the reviewed SHA became stale after `main` was merged into the PR branch. The current review-response fixes are bound to non-evidence -commit `e42b9506815a2eef155230928e791d5a737a6155` and must be pushed and +commit `6966c868b9a5f931b91f900ec754044cb61fabba` and must be pushed and checked again before merge. ## Remaining Risks From 9872ff6b9a4b3104d36f87a7d4e0af14dd1e9a4e Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 17:38:19 +0100 Subject: [PATCH 08/14] Clarify authorization implementation gate --- .../chunks/WS-AUTH-001-01-adopt-authorization-baseline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md index c0bf7f288..0b05b9bb8 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md @@ -119,7 +119,7 @@ adding permanent /v1 aliases - Future WS-POL chunks remain gated by explicit start signals and authorization impact review. - Roadmap status names WS-AUTH-001 as current priority, records POL-002 chunks - 01/02 merged and 03 handled separately in PR #90, and defers review + 01/02 merged and 03 handled separately in PR #90, and defers authorization implementation until auth proof. - Canonical vocabulary distinguishes `worker` as a task-lifecycle persona and attribution term from `submitter` as the persisted exact-project grant. From e3344b09c3e3c9c670d20e6b1403e23507c68249 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 17:43:55 +0100 Subject: [PATCH 09/14] Keep authorization initiative outside post-submit PR --- .../CHUNK_MAP.md | 4 ++-- .../DECISIONS.md | 9 +++------ .../DISCOVERY.md | 4 ++-- .../INTENT.md | 7 ++----- .../PLAN.md | 2 +- .../RISKS.md | 2 +- .../STATUS.md | 7 +++---- .../WS-AUTH-001-01-adopt-authorization-baseline.md | 6 ++---- .../WS-AUTH-001-12-project-mutation-cutover.md | 3 +-- .../chunks/WS-AUTH-001-16-evidence-live-proof.md | 6 +++--- ...AUTH-001-PLAN-authorization-service-planning.md | 5 ++--- .../WS-AUTH-001-PLAN-internal-review-evidence.md | 14 ++++---------- 12 files changed, 26 insertions(+), 43 deletions(-) diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md index b2a03012b..5cffa18be 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md @@ -65,8 +65,8 @@ WS-AUTH-001-PLAN - Chunks 11-15 migrate bounded complete product/system surfaces. - Chunk 16 proves the complete initiative; it does not backfill missing audit or idempotency evidence. -- `WS-POL-002-03` later resumed by explicit user start and is tracked in PR #90. - Future WS-POL chunks remain inactive until their own explicit start signals. +- `WS-POL-002-03` remains paused until the relevant project authorization + cutover is complete and the user explicitly resumes it. ## Stop condition diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md index c3fc561eb..6edac19a3 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md @@ -17,15 +17,12 @@ specification's `/v1` examples will be reconciled during the baseline-adoption chunk. Workstream will not expose two versioned route trees as permanent aliases. -## D3: Prioritize auth before further WS-POL expansion +## D3: Prioritize auth before WS-POL-002-03 Status: accepted by the user on 2026-07-11. -`WS-POL-002` was paused after merged chunk 02 when this plan was written. -`WS-POL-002-03` later resumed by explicit user start and is tracked in PR #90. -Future WS-POL chunks remain inactive until their own explicit start signals and -must account for the authorization direction before changing protected -surfaces. +`WS-POL-002` is paused after merged chunk 02. New post-submit approval APIs must +not be built on authority rules that have been declared obsolete. ## L0 human approval boundary diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md index 8777d128d..67894ea9f 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md @@ -128,13 +128,13 @@ requires explicit review in the token-verifier chunk. | Stale queued authority | Jobs may carry authority that has been revoked. | Re-resolve actor/grant state before actor-attributed commits. | | Claim/PII leakage | Current registry persists sanitized claim snapshots and role observations. | Minimize persisted identity data; never persist raw token/JWKS material. | | Namespace drift | New specs say `/v1`; repo uses `/api/v1`. | Record `/api/v1` as the adopted repository override and update generated/reference artifacts coherently. | -| Current initiative interruption | `WS-POL-002` was incomplete after chunk 02 when this plan was written. | Historical: chunk 03 later resumed by explicit user start and is tracked in PR #90; future chunks still need explicit starts. | +| Current initiative interruption | `WS-POL-002` is incomplete after chunk 02. | Mark it paused, do not implement chunk 03 until auth foundation is ready. | ## Unknowns/questions for human No blocking product questions remain for planning. The user explicitly adopted `WS-AUTH-001`, retained `/api/v1`, and prioritized auth before -future WS-POL chunks after `WS-POL-002-03`. +`WS-POL-002-03`. Production deployment inputs remain externally supplied: diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md index fee5680af..7b5c58614 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md @@ -118,9 +118,7 @@ namespace and remains canonical. - Existing task lifecycle behavior except the explicit, audited release of an exclusive assignment when its actor/link/project authority is invalidated. - CI, test, documentation, and internal-review gates. -- `WS-POL-002-03` later resumed by explicit user start and is tracked in PR #90. - Future WS-POL chunks still require explicit starts after their predecessors - merge and memory is updated. +- `WS-POL-002-03` remains paused until the authorization foundation is ready. ## How this will be proven @@ -141,8 +139,7 @@ Resolved: - `WS-AUTH-001` is authoritative and supersedes the token-role bootstrap. - `/api/v1` remains the canonical API namespace. -- `WS-AUTH-001` was prioritized before future WS-POL expansion; `WS-POL-002-03` - is now an active exception tracked in PR #90 after explicit user start. +- `WS-AUTH-001` is prioritized before `WS-POL-002-03`. Pending before `WS-AUTH-001-01` activation: diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md index 497cc39c1..8e5c4723a 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md @@ -55,7 +55,7 @@ its old token-role authorization. No command accepts token role or local grant as alternate sufficient proof. Project configuration moves first because it is required to create project -grants and safely continue future WS-POL work after PR #90. Task/submission/checker access follows +grants and later resume `WS-POL-002-03`. Task/submission/checker access follows after exact-project contributor grants and resource loaders exist. Chunk 06 preserves task claim/start/submission operability through an explicitly diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md index c72037788..16f6e999f 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md @@ -28,7 +28,7 @@ | A11 | API namespace forks | Client and documentation drift | Adopt `/api/v1` only and update references together | Route/OpenAPI and stale-reference scan | | A12 | Existing intake regresses | Project/task/checker pipeline stops | Run full current suite and API drill after actor migration and each cutover surface | Existing backend suite and live drill | | A13 | Auth initiative becomes one oversized PR | Review failure and hidden coupling | Sixteen bounded implementation chunks, one active at a time | Circuit-breaker and PR-size evidence | -| A14 | Future WS-POL work resumes on obsolete auth | Rework and inconsistent authority | Keep future WS-POL chunks inactive until explicit starts and authorization impact is reviewed | Loop-memory gate | +| A14 | WS-POL work resumes on obsolete auth | Rework and inconsistent authority | Keep WS-POL-002-03 paused in durable loop state | Loop-memory gate | | A15 | Authority mutation ships before durable evidence | Missing provenance cannot be reconstructed | Introduce correlation/idempotency/shared audit with canonical actor persistence | Atomic state+idempotency+event tests in every authority chunk | | A16 | Identity-link revocation strands final administrator | Administrative lockout despite active grant row | Apply AuthorityControl lock to link revoke plus grant/profile changes | Mixed concurrent link/grant/profile final-admin tests | | A17 | Canonical actor migration deletes typed-profile workflow eligibility before task/submission cutover | An intermediate merged release cannot claim, start, or submit work | Bounded non-authoritative workflow-eligibility adapter in chunk 06; remove task consumers in 13 and final consumer plus adapter in 14 | Full suite/API drill after chunks 06, 13, 14, and scanner proof in 15 | diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md index a86796846..c84d939fa 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md @@ -9,10 +9,9 @@ actionable findings, then its final check was cancelled when the PR closed. The initiative is stopped at the L0 human checkpoint: D1-D3 are approved; D4-D10 require explicit durable approval before implementation. -## Checkpointed planning artifact +## Active planning chunk -`WS-AUTH-001-PLAN` is merged and stopped at the L0 human checkpoint. No active -planning chunk is running. +None. ## Active implementation chunk @@ -54,7 +53,7 @@ implementation start signal. Internal review evidence is recorded at `reviews/WS-AUTH-001-PLAN-internal-review-evidence.md` and binds reviewed SHA -`6966c868b9a5f931b91f900ec754044cb61fabba`. +`5739e1d6fc8df0fa620bd007c45e370530ac8d12`. Production issuer configuration and legacy non-test actor classification are future implementation/live-proof inputs and are tracked explicitly in diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md index 0b05b9bb8..719b8187f 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-01-adopt-authorization-baseline.md @@ -116,11 +116,9 @@ adding permanent /v1 aliases `docs/reference_specs/README.md` records their hashes/status and the `/api/v1` override; canonical reconciled text lives separately in `docs/spec_authorization_service.md`. -- Future WS-POL chunks remain gated by explicit start signals and authorization - impact review. +- `WS-POL-002-03` is durably paused behind the auth initiative. - Roadmap status names WS-AUTH-001 as current priority, records POL-002 chunks - 01/02 merged and 03 handled separately in PR #90, and defers authorization - implementation until auth proof. + 01/02 merged and 03 paused, and defers review implementation until auth proof. - Canonical vocabulary distinguishes `worker` as a task-lifecycle persona and attribution term from `submitter` as the persisted exact-project grant. - Every current operational override/repair command is inventoried and assigned diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md index 616a89745..a4eed9c3e 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md @@ -13,8 +13,7 @@ provenance. ## Why this chunk exists This completes project authorization and unblocks later resumption of -the project setup approval surface without implementing unrelated WS-POL -runtime behavior. +`WS-POL-002-03` without implementing that paused chunk. ## Approved plan reference diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md index d8d54e122..006d15939 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md @@ -62,7 +62,7 @@ review/contribution/compensation implementation production credentials or private keys in fixtures/evidence direct database bootstrap or grant edits in live proof loosening issuer, scope, permission, or resource guards -starting future WS-POL chunks automatically +starting WS-POL-002-03 automatically ``` ## Acceptance criteria @@ -100,8 +100,8 @@ starting future WS-POL chunks automatically production dependency change requires separately recorded explicit human approval before modification. - No obsolete token-role authorization remains in runtime code. -- Initiative memory records proof and leaves future WS-POL chunks inactive - until explicit user start signals. +- Initiative memory records proof and leaves `WS-POL-002-03` inactive until an + explicit user resume signal. ## Verification commands diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md index 53863faae..66986acb8 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PLAN-authorization-service-planning.md @@ -66,8 +66,7 @@ review, contribution, compensation, frontend, or WS-POL implementation - Every implementation chunk has allowed files, exclusions, acceptance criteria, verification, reviewers, human focus, and stop conditions. - The plan preserves `/api/v1`, prevents dual authority, handles legacy actor - classification fail-closed, and records authorization priority for future - WS-POL chunks. + classification fail-closed, and pauses `WS-POL-002-03`. - Required internal plan reviews pass and all valid findings are resolved or documented. - The plan distinguishes approved L0 direction from proposed L0 decisions and @@ -100,7 +99,7 @@ git diff --check ## Human review focus Review the authority precedence, migration safety, chunk size/order, `/api/v1` -decision, WS-POL follow-up gating, and proof strategy. +decision, WS-POL pause, and proof strategy. ## Stop conditions diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md index 3ed67fc71..59fce435c 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-PLAN-internal-review-evidence.md @@ -10,9 +10,9 @@ valid findings addressed: yes ## Reviewed Revision -Reviewed code SHA: 6966c868b9a5f931b91f900ec754044cb61fabba +Reviewed code SHA: 5739e1d6fc8df0fa620bd007c45e370530ac8d12 -Reviewed at: 2026-07-11T16:10:55Z +Reviewed at: 2026-07-11T14:08:40Z Reviewer run IDs: senior-engineering=/root/pdf_attr_engineering_review; QA/test=/root/pdf_attr_quality_review; security/auth=/root/pdf_attr_ci_docs_security_review; product/ops=/root/pdf_attr_quality_review; architecture=/root/pdf_attr_engineering_review; docs=/root/pdf_attr_ci_docs_security_review; CI-integrity=/root/pdf_attr_ci_docs_security_review; reuse/dedup=/root/pdf_attr_engineering_review; test-delta=/root/pdf_attr_quality_review @@ -34,14 +34,9 @@ Scope: - Preserved intermediate-release intake operability and revision obligations, assigned every temporary compatibility consumer and deletion owner, and prohibited test/CI/dependency bypasses. -- At planning time, paused `WS-POL-002-03` and left every implementation chunk - inactive; `WS-POL-002-03` later resumed by explicit user start in PR #90. +- Paused `WS-POL-002-03` and left every implementation chunk inactive. - Recorded D1-D3 as user-approved L0 direction and D4-D10 as an explicit human approval gate before `WS-AUTH-001-01` activation. -- Reconciled PR #90 loop-state wording across WS-AUTH artifacts so historical - pause language does not remain an active blocker for the already-started - `WS-POL-002-03` chunk. Related wording touched `WS-AUTH-001-01`, - `WS-AUTH-001-12`, `WS-AUTH-001-16`, and `WS-AUTH-001-PLAN` records. ## Reviewer Results @@ -121,5 +116,4 @@ Results: No implementation chunk is active. Do not activate `WS-AUTH-001-01` without explicit human approval of D4-D10 and a separate implementation start signal. -Do not start future WS-POL chunks without explicit user start and authorization -impact review. +Do not resume `WS-POL-002-03` while authorization remains the priority. From 82af3add50d0688bd5c69cdf6203a526de4e45f5 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Sat, 11 Jul 2026 17:47:16 +0100 Subject: [PATCH 10/14] Align post-submit activation documentation --- .../WS-POL-002-03-post-submit-policy-approval-visibility.md | 3 +++ docs/architecture_lifecycle_state_machine.md | 2 +- docs/current_system_data_flow.html | 4 ++-- docs/operations_queue_policy.md | 6 ++++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/chunks/WS-POL-002-03-post-submit-policy-approval-visibility.md b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/chunks/WS-POL-002-03-post-submit-policy-approval-visibility.md index 1b7c88ec1..69934aa21 100644 --- a/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/chunks/WS-POL-002-03-post-submit-policy-approval-visibility.md +++ b/.agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/chunks/WS-POL-002-03-post-submit-policy-approval-visibility.md @@ -59,7 +59,10 @@ backend/tests/test_projects.py backend/tests/test_auth.py docs/product_first_user_flows.md docs/operations_project_operating_manual.md +docs/operations_queue_policy.md docs/architecture_data_model.md +docs/architecture_lifecycle_state_machine.md +docs/current_system_data_flow.html .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/** .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md diff --git a/docs/architecture_lifecycle_state_machine.md b/docs/architecture_lifecycle_state_machine.md index f5d274723..aaa1ecd9b 100644 --- a/docs/architecture_lifecycle_state_machine.md +++ b/docs/architecture_lifecycle_state_machine.md @@ -48,7 +48,7 @@ Required before leaving: ### SCREENING -The task is structurally prepared but not yet released. This is the pre-release quality gate used to catch weak guides, vague acceptance criteria, missing submission artifact requirements, bad payment policy, missing generated project pre-submit checker policy, missing post-submit checker policy, missing review policy, or missing revision policy before workers see the task. +The task is structurally prepared but not yet released. This is the pre-release quality gate used to catch weak guides, vague acceptance criteria, missing submission artifact requirements, bad payment policy, missing generated project pre-submit checker policy, missing approved generated project post-submit checker policy with matching provenance, missing review policy, or missing revision policy before workers see the task. Required before entering: diff --git a/docs/current_system_data_flow.html b/docs/current_system_data_flow.html index bec135480..f489ba402 100644 --- a/docs/current_system_data_flow.html +++ b/docs/current_system_data_flow.html @@ -483,7 +483,7 @@

Project guide and policy are prepared

3

Guide activation locks contract

-

Activation validates a passing or acknowledged sufficiency report, immutable guide source snapshot, approved submission artifact policy, effective project submission artifact policy hash, project pre-submit checker compiled bundle hash, registered post-submit checker names, review policy allowed decisions, revision states, and payment policy. Task readiness later validates that the task locks the applicable guide snapshot, effective project submission artifact policy hash, and pre-submit checker bundle hash.

+

Activation validates a passing or acknowledged sufficiency report, immutable guide source snapshot, approved submission artifact policy, effective project submission artifact policy hash, project pre-submit checker compiled bundle hash, approved generated project post-submit checker policy with matching guide, source snapshot, effective project policy, and pre-submit checker provenance, review policy allowed decisions, revision states, and payment policy. Task readiness later validates that the task locks the applicable guide snapshot, effective project submission artifact policy hash, and pre-submit checker bundle hash.

status=active one active guide @@ -628,7 +628,7 @@

Durable Records Created Along The Way