Skip to content

feat(a4): persist session-bound search issues - #398

Merged
monkey1sai merged 2 commits into
mainfrom
feat/a4-s4c-session-issue-proxy
Jul 24, 2026
Merged

monkey1sai merged 2 commits into
mainfrom
feat/a4-s4c-session-issue-proxy

Conversation

@monkey1sai

@monkey1sai monkey1sai commented Jul 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add a session-scoped coordinator route for creating an Issue from trusted A4 search evidence.
  • Persist immutable A4 evidence, three distinct digests, atomic proof consumption, exact replay, and generic Issue-surface hiding in governance-service.
  • Bound proof issuance, response size, session/principal quotas, numeric wire representation, and shared internal-token validation.
  • Keep the production-mounted route fail closed while authentic lease capability remains lab_unverified.

Scope and completion

This is the S4-C backend slice of a4-semantic-search-model-qa. OpenSpec tasks 4.1-4.4 and 4.7 are complete. Task 3.8 remains open because the production resolver cannot yet produce an authentic verified lease capability. Task 4.5 still needs browser-memory draft recovery/recheck UI, and task 4.6 still needs the expiry-plus-clock-skew key-retirement operational contract.

Full completion claimed: no.

AI Coding Governance

Item Result
Change lane G
Behavior contract changed yes
Linked issue OpenSpec change a4-semantic-search-model-qa; no standalone GitHub issue
Requirement source docs/plans
CODEOWNERS / owner review requested through repository branch protection; local correctness and security reviewers accepted
GitNexus evidence detect_changes risk=CRITICAL: 20 files, 224 symbols, 165 execution flows on final head; explicit user sign-off recorded; correctness and security reviewers found no P1/P2
Browser E2E evidence backend-only S4-C slice; not run; production-mounted Issue mutation remains fail-closed with 503 while lease capability is lab_unverified
Agent workflow changed? no; no agent instruction, hook, plugin, MCP, or workflow contract changed
Required checks expected CI / Agent Governance / PR Review Agent

Deploy Path Verification

Item Result
Affects runtime / docker / Kit / viewer / ports / env? yes: coordinator and governance-service runtime API behavior; no Docker, Kit, viewer, port, or env contract changes
Canonical deploy path updated? verified: no deploy-script update required; existing coordinator-to-governance loopback boundary is unchanged
New root script added? no
Deploy dry-run command not run; no deploy/script/compose change and production Issue mutation intentionally remains fail-closed
Full deploy tested not run; this backend slice does not claim production operability
Verify command npm run verify in bim-review-coordinator; python -m pytest tests/ -q -p no:cacheprovider in governance-service
Frontend URL verified no frontend route changed
Evidence path commits f8bf041 and dc20f52; affected tests under bim-review-coordinator/tests/ and governance-service/tests/

Validation

  • Coordinator targeted A4 search/Issue tests: 26 passed.
  • Coordinator npm run verify: TypeScript build passed; 65 test files and 724 tests passed.
  • Governance targeted search/handoff/Issue/BCF/diff tests: 103 passed, 1 skipped.
  • Governance full suite: 275 passed, 2 skipped.
  • npx openspec validate a4-semantic-search-model-qa --strict: passed.
  • npx openspec validate --all --strict: 64 passed, 0 failed.
  • git diff --check and staged trailing-whitespace/credential scans: passed; production credential signatures: 0.
  • Frozen governanceProxy.ts, viewer, Kit Manager, and streaming scopes: zero diff.
  • Local correctness review: accept, no P1/P2.
  • Local security review: accept, no P1/P2.
  • CodeRabbit security finding fixed in dc20f52: response exact-echo allowlist is restricted to title/description/assignee; snapshot-only path-like strings now fail closed.

Known Risks

  • Ruff was unavailable in the current Python environment (No module named ruff), so no Ruff result is claimed.
  • Browser, Kit, live-model, deployment, and design dual gates were not run; this PR does not claim full user-facing completion.
  • Non-loopback plain-HTTP governance origins remain a low/P3 transport-hardening concern; current deployment contract remains loopback.
  • Authentic shared lease capability, browser expiry recovery, and key-retirement clock-skew operations remain follow-up work.

Summary by CodeRabbit

  • New Features
    • Added session-scoped A4 issue creation from confirmed search results.
    • Added secure, evidence-backed issue persistence with replay-safe behavior.
    • Added deterministic fallback indicators and bounded search/proof responses.
  • Security
    • Strengthened authentication, session validation, evidence binding, and fail-closed handling.
    • A4-sourced issues are hidden from standard issue browsing and transitions.
  • Bug Fixes
    • Improved protection against forged, expired, conflicting, or cross-session evidence.
  • Documentation
    • Documented the new A4 issue endpoints, validation requirements, and evidence handling.

Copilot AI review requested due to automatic review settings July 24, 2026 02:34
@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The PR adds a session-scoped A4 Issue forwarding route, a coordinator-only governance endpoint, replay-safe A4 evidence persistence, stricter internal authentication and proof verification, bounded A4 search responses, and extensive integration and persistence tests.

A4 Issue Flow

Layer / File(s) Summary
Coordinator validation and forwarding
bim-review-coordinator/src/routes/a4IssueRoutes.ts, bim-review-coordinator/src/routes/a4SearchRoutes.ts, bim-review-coordinator/src/app.ts, bim-review-coordinator/tests/*, bim-review-coordinator/README.md
The coordinator validates session, authority, draft fields, and evidence binding before forwarding trusted deterministic requests to governance-service.
Trusted issue creation and persistence
governance-service/issues/*, governance-service/app.py, governance-service/tests/test_a4_issues.py, governance-service/README.md
The internal endpoint validates snapshots and proofs, atomically creates or replays A4 issues, stores immutable evidence, and hides A4 records from generic issue APIs.
Internal authentication and restart-safe proofs
governance-service/search/internal_auth.py, governance-service/search/api.py, governance-service/search/proofs.py, governance-service/tests/*
Internal tokens require valid printable ASCII configuration, while proofs gain wire-stable snapshots, quotas, embedded claims, discard support, and restart-aware verification.
Bounded search and degradation propagation
governance-service/search/engine.py, governance-service/tests/test_search_model.py, openspec/changes/a4-semantic-search-model-qa/tasks.md
Search results and proof attachments are bounded by field, row, attempt, and byte limits, with omission markers and deterministic-degradation state propagated through fallback confirmation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Coordinator
  participant GovernanceAPI
  participant ProofRegistry
  participant IssueStore
  Client->>Coordinator: Submit session-scoped A4 issue draft
  Coordinator->>Coordinator: Authenticate and validate binding
  Coordinator->>GovernanceAPI: Forward trusted A4 request
  GovernanceAPI->>ProofRegistry: Verify proof and snapshot
  GovernanceAPI->>IssueStore: Create or replay issue
  IssueStore-->>GovernanceAPI: Issue and replay status
  GovernanceAPI-->>Coordinator: Issue response
  Coordinator-->>Client: Sanitized response
Loading

Possibly related PRs

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.49% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding session-bound A4 search issue persistence.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/a4-s4c-session-issue-proxy

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

❤️ Share

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR implements the S4-C backend slice of the a4-semantic-search-model-qa OpenSpec change: it adds an end-to-end path for turning a trusted A4 semantic-search result row into a persisted governance Issue. A new coordinator-only route (/api/governance/issues/from-a4-search/for-session/{session_id}) reauthorizes the current session/principal, strips browser-supplied authority, and forwards to a new governance route (/api/internal/a4/issues/from-search) that verifies a signed row proof and atomically persists immutable A4 evidence. It fits into the existing coordinator→governance loopback boundary and the scoped-only A4 search design, keeping the production-mounted mutation fail-closed (503) while the authentic lease capability remains lab_unverified.

Changes:

  • Proof hardening: embeds authenticated expiry + snapshot-hash claims inside the opaque proof id (restart/rotation-safe verification), adds per-binding/per-principal quotas, and JSON-wire-stable numeric normalization so Python↔Node round-trips preserve signed bytes.
  • Persistence + replay: new additive a4_issue_evidence table with three digests (snapshot_hash, proof_digest, creation_request_hash), single-transaction create, constant-time exact-replay that returns the original Issue even after key retirement, and authorization-before-digest ordering to avoid a proof-existence oracle.
  • Surface hiding + bounded responses: generic Issue list/detail/transition fail closed on a4_search records; search responses are size-bounded (row projection, honest truncation, proof attachment budgeting) and share printable-ASCII internal-token validation.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated no comments.

Show a summary per file
File Description
governance-service/search/proofs.py Embedded-claim proof ids, quota accounting/release, restart-safe verify, wire-stable snapshot normalization, discard()
governance-service/search/engine.py Response byte budgeting, bounded value projection, proof attachment loop, corrected degraded_to_deterministic semantics
governance-service/search/internal_auth.py New shared fail-closed internal-token validation helpers
governance-service/search/api.py Uses shared internal_auth; removes duplicated token logic
governance-service/issues/store.py a4_issue_evidence schema, atomic create_a4_issue, find_a4_issue_replay, A4 hiding in list_issues
governance-service/issues/api.py Hides A4 records from generic get/transition endpoints
governance-service/issues/a4_api.py New coordinator-only A4 Issue creation route with snapshot/binding validation
governance-service/issues/__init__.py Exports new A4 exceptions
governance-service/app.py Mounts the A4 Issue router
bim-review-coordinator/src/routes/a4IssueRoutes.ts New scoped session route: authorization, draft sanitization, trusted-context injection
bim-review-coordinator/src/routes/a4SearchRoutes.ts Exports forwardTrustedA4/GovernanceTimeoutBudget; adds exact-echo allowlist and ASCII token check
bim-review-coordinator/src/app.ts Wires the A4 Issue route before the generic proxy
governance-service/README.md, bim-review-coordinator/README.md Document the new route and token constraints
openspec/changes/.../tasks.md Marks tasks 4.1–4.4/4.7 complete with a scope note
governance-service/tests/*, bim-review-coordinator/tests/* Extensive new/updated coverage (persistence, replay, quotas, budgeting, coordinator forwarding)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bim-review-coordinator/src/routes/a4IssueRoutes.ts`:
- Around line 353-362: Remove collectExactStringEchoes from the
allowedResponseEchoes construction in the route handling the draft value, and
retain only the explicit title, description, and assignee strings. Ensure no
other browser-controlled a4_evidence_snapshot fields are added to the echo
allowlist, while preserving the existing normalization and optional-field
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 60345739-1020-4ca6-802c-acd8c2505ab9

📥 Commits

Reviewing files that changed from the base of the PR and between a9f68c6 and f8bf041.

📒 Files selected for processing (20)
  • bim-review-coordinator/README.md
  • bim-review-coordinator/src/app.ts
  • bim-review-coordinator/src/routes/a4IssueRoutes.ts
  • bim-review-coordinator/src/routes/a4SearchRoutes.ts
  • bim-review-coordinator/tests/governance-issue-from-a4-session.test.ts
  • bim-review-coordinator/tests/governance-search-for-session.test.ts
  • governance-service/README.md
  • governance-service/app.py
  • governance-service/issues/__init__.py
  • governance-service/issues/a4_api.py
  • governance-service/issues/api.py
  • governance-service/issues/store.py
  • governance-service/search/api.py
  • governance-service/search/engine.py
  • governance-service/search/internal_auth.py
  • governance-service/search/proofs.py
  • governance-service/tests/test_a4_issues.py
  • governance-service/tests/test_search_handoff_api.py
  • governance-service/tests/test_search_model.py
  • openspec/changes/a4-semantic-search-model-qa/tasks.md

Comment thread bim-review-coordinator/src/routes/a4IssueRoutes.ts

@monkey1sai monkey1sai left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Final risk-loop review

Verdict: Accept — no unresolved blocking findings.

  • The response-echo allowlist concern was fixed in dc20f52: browser-controlled snapshot strings are no longer recursively allowlisted; only normalized title, description, and assignee echoes remain.
  • Regression coverage now proves a path-like snapshot value is sanitized to 502; the CodeRabbit thread is resolved.
  • Local gates on the final head: coordinator build + 65 files / 724 tests; targeted Issue suite 7/7; PR preflight passed; git diff --check passed.
  • GitHub required checks on dc20f52 are green; PR is mergeable and clean.

Non-blocking gaps: Ruff is unavailable in this environment; browser/Kit/live-model/design gates were not applicable to this backend-only slice, so full user-facing completion is not claimed. The broad PR remains GitNexus CRITICAL by scope, covered by the recorded explicit sign-off; the repair-specific delta is LOW.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f8bf0412d9

ℹ️ About Codex in GitHub

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

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

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

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

Comment on lines +166 to +167
elif accepted_prim is not None or row_prim is not None or body.usd_prim_path is not None:
raise _error(422, "a4_issue_mapping_mismatch")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject proofs from unaccepted mappings

When a search runs with element_mapping_path missing or rejected as fake, search/engine.py only records path_missing/rejected_fake in top-level evidence_refs; the signed row snapshot still has mapping_observed=false and null prims. This branch then lets that snapshot fall through as valid, so the new A4 Issue route can persist A4 provenance for rows whose mapping source was not actually accepted. Include the mapping-join status in the signed snapshot and reject non-accepted mapping states before creating the Issue.

AGENTS.md reference: governance-service/AGENTS.md:L31-L33

Useful? React with 👍 / 👎.

deps,
"/api/internal/a4/issues/from-search",
"deterministic",
{ ...draft.value, a4_trusted_context: trusted },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Recheck the session binding after upstream create

If the primary lease or active stage binding changes after resolveSession/snapshotMatchesCurrentBinding but before the governance call commits, this forwards the stale trusted object and governance has no way to know it is no longer current. In that race, an A4 Issue can be persisted for a proof tied to a previous artifact/revision/principal authorization; re-resolve and compare the binding after the upstream verification window, or make the create conditional on a fresh current binding.

AGENTS.md reference: bim-review-coordinator/AGENTS.md:L18-L19

Useful? React with 👍 / 👎.

model_version_id=None,
kind=None,
*,
include_a4: bool = False,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve A4 issues in downstream issue workflows

Because include_a4 now defaults to false at the store layer, existing internal callers such as /api/bcf/export and /api/diffs/{diff_id}/issue-impact also silently drop confirmed A4 records even though they are stored as formal kind='issue' rows with ifc_guid and model_version_id. If the goal is only to hide generic list/detail/transition until session-authorized lifecycle routes exist, pass an explicit include flag or add authorized read paths for BCF export and diff impact; otherwise user-confirmed A4 issues will be missing from governance outputs.

AGENTS.md reference: governance-service/AGENTS.md:L14-L16

Useful? React with 👍 / 👎.

@monkey1sai
monkey1sai merged commit 64cadb0 into main Jul 24, 2026
16 of 17 checks passed
@monkey1sai
monkey1sai deleted the feat/a4-s4c-session-issue-proxy branch July 24, 2026 02:58
monkey1sai added a commit that referenced this pull request Jul 24, 2026
* docs(evidence): record PR 398 test-deploy risk verification

* docs(evidence): complete PR 398 test deploy verification

* docs(evidence): clarify PR 398 verification scope
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants