Skip to content

[codex] Add Notary CEL integration - #219

Open
jeremi wants to merge 9 commits into
19.0from
x/notary-verification-gaps
Open

[codex] Add Notary CEL integration#219
jeremi wants to merge 9 commits into
19.0from
x/notary-verification-gaps

Conversation

@jeremi

@jeremi jeremi commented May 29, 2026

Copy link
Copy Markdown
Member

Summary

Adds the Notary CEL integration and a follow-up correction pass for the reviewer-identified verification gaps.

What changed

  • Adds spp_notary_client support for Registry Notary discovery, evaluate, batch-evaluate, typed errors, sanitized outgoing logging, and versioned claim refs.
  • Adds spp_notary_evidence provider configuration, claim catalog rows, CEL external variable generation, Notary evaluate hooks, cache writes, stale-cache audit behavior, and catalog sync UX.
  • Replaces the placeholder catalog sync with preview/confirm rows for create, update, version drift, unavailable, no change, and accessor collision blocking.
  • Makes pinned_version an actual version string, treats upstream version bumps as version_drift, and keeps one claim row per provider/external ID.
  • Adds Odoo-visible tests for the Notary client and expands Notary evidence coverage.

Validation

  • ruff check spp_notary_client spp_notary_evidence
  • python -m pytest spp_notary_client/tests -q generated 20 passed, 1 skipped
  • ./spp t spp_notary_client generated 2 passed
  • ./spp t spp_notary_evidence generated 23 passed
  • ./spp t spp_cel_domain generated 590 passed
  • bash .claude/scripts/audit-security.sh spp_notary_evidence generated 0 errors, 0 warnings
  • bash .claude/scripts/audit-security.sh spp_notary_client generated 0 errors, 0 warnings
  • python -m compileall -q spp_notary_client spp_notary_evidence
  • git diff --check

Remaining gaps called out for reviewers

  • Transaction/session-scoped batching across multiple variables is still not implemented. Current behavior batches subjects per variable.
  • Wizard blocks accessor collisions but does not yet provide a full operator alias/adopt workflow or active-reference rename scan.
  • notary_subject_log_secret is not auto-generated at install time. Subject-scoped logged calls now fail safely if it is missing.
  • Purpose-layer labeling still cannot distinguish claim-default purpose from explicit evaluation-context purpose inside the client.
  • Docker-compose integration test remains absent.

Comment thread spp_notary_evidence/wizards/catalog_sync_wizard.py Fixed

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces integration with Registry Notary evidence services, adding a pure Python client (spp_notary_client) and an Odoo integration module (spp_notary_evidence) to support CEL external variables. Key changes include scoping cache lookups to specific providers, adding a catalog sync wizard, and implementing live evaluation hooks. The feedback highlights several critical performance and resource management improvements: batching cache misses in _exec_external_metric to avoid N+1 HTTP requests, implementing context manager methods in NotaryClient to prevent connection leaks, and batching database creations in _apply_notary_claim_catalog to reduce database roundtrips.

Comment thread spp_cel_domain/models/cel_executor.py Outdated
Comment thread spp_notary_client/services/client.py
Comment thread spp_notary_evidence/models/data_provider.py
@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.73189% with 56 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.95%. Comparing base (c660896) to head (b84609c).

Files with missing lines Patch % Lines
spp_notary_evidence/models/data_provider.py 92.26% 25 Missing ⚠️
spp_notary_client/services/audit_log.py 85.41% 7 Missing ⚠️
spp_notary_client/services/client.py 96.83% 7 Missing ⚠️
spp_notary_evidence/models/notary_claim.py 94.44% 6 Missing ⚠️
spp_cel_domain/models/cel_executor.py 92.45% 4 Missing ⚠️
spp_notary_client/services/schemas.py 97.08% 3 Missing ⚠️
spp_cel_domain/models/data_evaluator.py 90.00% 1 Missing ⚠️
spp_cel_domain/models/data_provider.py 94.11% 1 Missing ⚠️
spp_notary_client/__manifest__.py 0.00% 1 Missing ⚠️
spp_notary_evidence/__manifest__.py 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             19.0     #219      +/-   ##
==========================================
+ Coverage   71.50%   71.95%   +0.45%     
==========================================
  Files        1001     1015      +14     
  Lines       58626    59685    +1059     
==========================================
+ Hits        41921    42948    +1027     
- Misses      16705    16737      +32     
Flag Coverage Δ
spp_analytics 93.13% <ø> (ø)
spp_api_v2 80.33% <ø> (ø)
spp_api_v2_change_request 66.85% <ø> (ø)
spp_api_v2_cycles 71.12% <ø> (ø)
spp_api_v2_data 64.41% <ø> (ø)
spp_api_v2_entitlements 70.19% <ø> (ø)
spp_api_v2_gis 71.52% <ø> (ø)
spp_api_v2_products 66.27% <ø> (ø)
spp_api_v2_service_points 70.94% <ø> (ø)
spp_api_v2_simulation 71.12% <ø> (ø)
spp_api_v2_vocabulary 57.26% <ø> (ø)
spp_approval 50.29% <ø> (ø)
spp_audit 72.60% <ø> (ø)
spp_base_common 90.26% <ø> (ø)
spp_cel_domain 62.22% <93.25%> (+1.07%) ⬆️
spp_notary_client 95.74% <95.74%> (?)
spp_notary_evidence 94.19% <94.19%> (?)
spp_programs 64.84% <ø> (ø)
spp_registry 86.83% <ø> (ø)
spp_security 66.66% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
spp_cel_domain/models/data_value.py 77.52% <100.00%> (+1.21%) ⬆️
spp_notary_client/services/__init__.py 100.00% <100.00%> (ø)
spp_notary_client/services/exceptions.py 100.00% <100.00%> (ø)
spp_notary_evidence/__init__.py 100.00% <100.00%> (ø)
spp_notary_evidence/models/__init__.py 100.00% <100.00%> (ø)
spp_notary_evidence/models/cel_variable.py 100.00% <100.00%> (ø)
spp_notary_evidence/wizards/__init__.py 100.00% <100.00%> (ø)
spp_notary_evidence/wizards/catalog_sync_wizard.py 100.00% <100.00%> (ø)
spp_cel_domain/models/data_evaluator.py 53.47% <90.00%> (+1.50%) ⬆️
spp_cel_domain/models/data_provider.py 95.65% <94.11%> (+10.12%) ⬆️
... and 8 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jeremi
jeremi marked this pull request as ready for review May 29, 2026 11:21
@jeremi

jeremi commented May 29, 2026

Copy link
Copy Markdown
Member Author

Addressed the Gemini review items and rechecked CI.

Changes pushed:

  • Batched external metric cache misses through provider._compute_external_values() in spp_cel_domain.models.cel_executor, with base provider fallback retained.
  • Added context-manager support to NotaryClient so owned HTTP clients are closed and injected clients remain caller-owned.
  • Batched Notary catalog claim creation and preloaded existing claims in _apply_notary_claim_catalog() to avoid per-row search/create behavior.
  • Replaced the direct wizard state write with an explicit action_validate() path for the catalog sync wizard.
  • Applied CI formatter output for the XML/Python files flagged by pre-commit.

Verification:

  • Local pre-commit run --files ... passed for the PR file set.
  • Local ./spp t spp_notary_evidence passed: 23 passed, 0 failed, 0 errors.
  • CI is green on c0106274: build, pre-commit, CodeQL, Semgrep/GHAS, Gitleaks, dependency scan, Codecov, and all affected module tests pass, including spp_cel_domain, spp_notary_client, spp_notary_evidence, spp_api_v2, spp_programs, and spp_security.

I also resolved the Gemini review threads after applying the fixes.

@jeremi

jeremi commented May 29, 2026

Copy link
Copy Markdown
Member Author

@gemini-code-assist review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces the spp_notary_client and spp_notary_evidence modules to integrate Registry Notary evidence services with Odoo, allowing external CEL variables to resolve via provider-specific refresh hooks and scoped caching. Feedback on these changes highlights critical resource leaks where NotaryClient is instantiated without a context manager, a performance bottleneck in _ensure_cel_variable due to database operations inside a loop, and a potential crash during datetime parsing if datetime.fromisoformat raises an uncaught ValueError.

Comment thread spp_notary_evidence/models/data_provider.py
Comment thread spp_notary_evidence/models/data_provider.py
Comment thread spp_notary_evidence/models/data_provider.py
Comment thread spp_notary_evidence/models/notary_claim.py
Comment thread spp_notary_evidence/models/data_provider.py
@jeremi

jeremi commented May 29, 2026

Copy link
Copy Markdown
Member Author

Coverage and Gemini follow-up pushed through 8f6bcad9.

Coverage:

  • Patch coverage moved from 76.81913% / 223 missing lines to 95.46371% / 45 missing lines.
  • Codecov patch and project checks are passing.
  • spp_notary_client is 95.74% and spp_notary_evidence is 95.69%; the catalog sync wizard is 100%.
  • I added Odoo-runner coverage because Codecov is generated from the Odoo test matrix, not only the standalone pytest path.

Gemini:

  • Addressed the fresh Gemini comments by context-managing provider-created NotaryClient usage in catalog fetch, batch evaluate, and single evaluate paths.
  • Batched CEL variable lookup/create work in _ensure_cel_variable().
  • Hardened Notary datetime parsing so invalid upstream strings return None instead of crashing evaluation.
  • Replied to and resolved the Gemini threads.

Verification:

  • Local ./spp t spp_notary_client: 20 passed, 0 failed, 0 errors.
  • Local python -m pytest spp_notary_client/tests -q: 22 passed, 1 skipped.
  • Local ./spp t spp_notary_evidence: 33 passed, 0 failed, 0 errors.
  • Local pre-commit run --files ... passed for the touched Notary files.
  • CI on latest head is green: build, pre-commit, CodeQL, Semgrep/GHAS, Gitleaks, dependency scan, Codecov, and the full module test matrix. Trivy remains skipped as configured.

@jeremi

jeremi commented May 29, 2026

Copy link
Copy Markdown
Member Author

Addressed the consolidated review tail in b84609c1.

Fixed HIGH correctness/spec items:

  • stale_cache_with_audit now re-raises the original NotaryError when no stale row exists, instead of silently returning empty values.
  • Stale-cache audit payload now includes claim_id, evaluation_id, per-row HMAC subject_hash, stale_age_seconds, and expires_at. It refuses stale-audit fallback when notary_subject_log_secret is missing.
  • action_test_connection() now sends API keys using x-api-key by default, or a configured API-key header if provided, instead of Authorization: Bearer.
  • Notary cache reads/writes are partitioned by pinned version through params_hash, including executor cache reads and stale-cache lookups.
  • Batch subject-ID resolution now goes through the Notary unavailable policy path; null degrades to no values without calling the client.
  • Claim-default purpose now flows to Notary client audit logs as purpose_layer="claim_default".
  • Active CEL expressions now block Notary claim external-ID/provider renames that would change an accessor already referenced by active rules.

Operator/spec polish:

  • Added effective-purpose preview fields on Notary CEL variables and claim/provider views.
  • Added sensitive subject-ID warning on Notary providers.
  • Added Stale Cache Reads menu/action for Notary outgoing logs.
  • Grouped/decorated catalog-sync wizard diff rows by action and blocking severity.

Verification run locally:

  • ruff check ...: passed.
  • python -m compileall -q spp_cel_domain spp_notary_client spp_notary_evidence: passed.
  • git diff --check: passed.
  • ./spp t spp_notary_client: 21 passed, 0 failed, 0 errors.
  • ./spp t spp_notary_evidence: 36 passed, 0 failed, 0 errors.
  • ./spp t spp_cel_domain: 591 passed, 0 failed, 0 errors.
  • python -m pytest spp_notary_client/tests -q: 22 passed, 1 skipped.
  • pre-commit run --files ...: passed. Pylint still prints existing repo-level .pylintrc unknown-option warnings, but the hook exits 0.

Not addressed in this commit: the explicitly acknowledged PR-tail items around single-subject speculative session fetch, alias/adopt UX, group XML-ID naming deviation, and docker-compose e2e PR 8.

@gonzalesedwin1123 gonzalesedwin1123 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Expert review — verification-gap fixes are not complete

Thorough pass over both new modules, the spp_cel_domain changes, and the drift against today's 19.0 (the branch is 516 commits behind and conflicting). Findings below were verified against the code — several by executing it — not taken from the PR description. All suites are green on the branch (spp_notary_client 21/0/0 Odoo + 22 passed/1 clean skip host pytest, spp_notary_evidence 36/0/0, spp_cel_domain 591/0/0), ACLs exist for all new models, and the test quality is genuinely good (real non-admin ACL tests, real executor integration, mocking only at the HTTP boundary). The problems are in what the fixes claim versus what they do, and in gaps the "Remaining gaps" list doesn't mention.

Verdicts on the claimed fixes

spp_notary_client

Claim Verdict
Context-manager client lifecycle PARTIALwith paths correct (incl. injected-client nullcontext), but close() never resets _http_client (reuse-after-close raises raw RuntimeError), and the public _notary_client() helper leaks open httpx pools when used without with
Sanitized outgoing logging VALID for the logging code — but unmapped pydantic.ValidationError escapes to tracebacks with raw subject values (input_value=770123456789), and NotaryError.details["response"] carries whole raw response bodies
x-api-key default header VALID for the notary path — but the "or configured header" half is dead code (reads api_key_header/notary_api_key_header, neither exists on spp.data.provider), and the change to spp_cel_domain._test_connection regresses every existing provider that expected Authorization: Bearer (see Critical 4)
Typed errors, no raw leaks PARTIAL — 5 verified leak paths: httpx.DecodingError, TooManyRedirects, CookieConflict, InvalidURL/ValueError on malformed base_url, RuntimeError after close. Malformed/HTML 200 bodies fail open: _response_payload swallows to {} → valid empty response → "subject has no evidence"
Versioned claim refs + batch evaluate PARTIAL — versioning valid and tested; batching real, but no client-side batch cap (50,000 subjects accepted in one POST), retry_max is passed as "max_retries" and silently ignored, and per-item batch failures are dropped without reading item.errors

spp_notary_evidence / spp_cel_domain

Claim Verdict
stale_cache_with_audit re-raises original NotaryError PARTIAL — the re-raise is real, but per-item batch failures bypass the policy silently; _first_matching_resultNone bypasses it; and NotaryConfigurationError sits outside the try in the batch path but inside it in the single path (asymmetric raw traceback)
Audit payload keys + secret gate PARTIAL — keys present, gate real, but evaluation_id is always None in production: the code reads error.details["evaluation_id"] while the client sets details={"response": payload}. The test that "proves" it hand-constructs a details shape the client never produces. Also, the audit write is best-effort (log_call swallows all exceptions, return unchecked) — "with audit" is unenforced
Batched external metric cache misses VALID with caveats — no N+1 left; but the base fallback logs one warning per subject (2,000 per batch), and the external path skips preview_cache_only and async_threshold (Criticals 7, 8)
Batched catalog claim creation + preload PARTIAL — preload misses archived claims (active_test) → guaranteed IntegrityError on re-sync (Critical 5); updates and deactivation are still per-row writes
Wizard collision blocking + pinned_version PARTIAL — rows and pinned_version correct, but the collision block is wizard-UX only: the provider form's action_sync_notary_catalog, create(), and write() all bypass it, and _ensure_cel_variable silently adopts and rewrites any existing variable with the same name. The unique constraints are per-provider, so cross-provider accessor collisions are never blocked at the DB level

Critical (must fix)

  1. Batch responses can attribute one subject's claim value to a different subject. spp_notary_evidence/models/data_provider.py:385 falls back to the positional enumerate index when item.input_index is None (it is Optional in the schema). A server omitting it — or returning items only for succeeded subjects — writes the value to the wrong res.partner, persists it to spp.data.value, and CEL eligibility reads it. The existing input_index=None test uses a single subject, exactly the case that hides this. Match on item.subject identity; never positional order.
  2. The idempotency-key is an unkeyed, reproducible hash of the subject's national ID and never rotates. spp_notary_client/services/client.py:509-531 uses uuid5(NAMESPACE_URL, ...) — no secret, so anyone observing the header can confirm a guessed subject ID; and the key is identical for the same (subject, claim, purpose) forever, so any server honouring idempotency replays a cached evaluation indefinitely, silently defeating expires_at/TTL. Generate a random per-call key (stable only across _request retries), or HMAC the seed.
  3. Released spp_cel_domain is changed with no version bump, no HISTORY fragment, no README regen, and no migration — including a new required=True field (provider_kind), a read_values(..., params=) signature change, and a _provider_clause semantics change. Manifest still reads 19.0.2.0.0; 19.0 is at 19.0.2.1.0.
  4. _test_connection regressed for every existing provider: spp_cel_domain/models/data_provider.py:334-336 switches all providers from Authorization: Bearer to x-api-key, the config escape hatch reads fields that don't exist (dead code), and the new bearer auth type isn't handled there at all. This is out of the PR's stated scope — split it out or branch on provider_kind.
  5. Catalog re-sync crashes with an IntegrityError once any claim was archived. The preload Claim.search() is subject to active_test, so a claim that disappears and reappears upstream is routed to create() and violates the unique constraint. The wizard preview (One2many, active_test=False) meanwhile reports "no change" — preview and confirm disagree. Use with_context(active_test=False).
  6. Ordinary officers get an AccessError evaluating any notary metric. The evaluation path dereferences spp.notary.claim (ACL: notary groups only) and provider.code as the acting user with no sudo() (data_provider.py:259,287,375-377; cel_executor.py:1328,1333). The non-admin tests all use notary-group users, so they cannot catch this.
  7. Expression preview triggers live upstream disclosures. _exec_external_metric returns before preview_cache_only_mode is consulted, so previewing an expression ships subject national IDs to the provider even on deployments configured for cache-only previews.
  8. Unbounded synchronous fan-out. The external path iterates the entire base domain with no cap and no queue_job, skipping the async_threshold guard the indicator path has — a 1M-record cohort issues ~1,000 sequential HTTP calls inside one web transaction and discloses 1M IDs.
  9. The audited purpose is caller-forgeable. notary_purpose is read from cel_cfg or raw env.context (client-supplied over RPC) and becomes both the upstream data-purpose header and the recorded audit purpose. No allowlist, no binding to consent records — validate against registered purposes, default-deny.
  10. Cross-provider CEL variable hijack. _ensure_cel_variable (notary_claim.py:175-193) adopts any existing variable by name and rewrites source_type/external_provider_id/notary_claim_id. The slug join is ambiguous (provider x + claim y_z == provider x_y + claim z), so a notary manager on provider B can silently repoint provider A's live variable at B's base_url. The rename guard exists; an adopt/hijack guard doesn't.
  11. UnboundLocalError on empty cohorts: cache_params is assigned inside the batch loop and referenced after it (cel_executor.py:1328/1359); reachable whenever the SQL fast path doesn't short-circuit and the domain yields no ids.
  12. Rebase hazard — Data API exposure. Since #257 (merged 2026-06-30, after this branch's base), is_data_api_pullable returns True for exactly the variables this PR generates (source_type='external' + provider), so cached Notary claim values become retrievable through the generic /Data/pull API. spp_dci_indicators deliberately overrides this to exclude its providers; spp_notary_evidence needs the same decision made explicitly.

Rebase / coordination (516 commits behind, conflicting)

  • Textual conflicts: spp_cel_domain/models/cel_executor.py, spp_cel_domain/tests/__init__.py.
  • Semantic drift in the hooked region: upstream now derives params_hash from p.params (parameterized metrics) — this PR's external path ignores p.params entirely — and changed the as_root/override_domain materialization semantics.
  • Open PR #272 rewrites the same _provider_clause fallback this PR edits (same security direction, must be reconciled by hand; whoever lands second re-reviews).
  • spp_cel_domain version queue: 19.0 at 2.1.0, #272 → 2.1.1, this PR needs a higher bump plus HISTORY and CI-generated README.

Important (should fix)

  • Wrap every model_validate in a typed error carrying field paths only — pydantic messages currently put subject values into logs (hard no-PII rule).
  • Malformed/non-JSON 200 responses must be a typed error, not an empty "no evidence" result.
  • NotaryClientConfig default repr prints bearer_token, api_key, and subject_log_secretfield(repr=False) all three.
  • Per-call timeouts are ignored: the owned client is cached from the first config, and injected clients ignore timeout_seconds entirely; pass the timeout per-request.
  • base_url has no scheme/host validation (http:// and even file:/// normalize fine) and is writable by group_cel_domain_manager, who cannot read the bearer token — a repoint-and-exfiltrate path for both the token and subject IDs. Enforce https and consider a host allowlist.
  • Secrets are plaintext Char columns while spp.data.credential (encrypted, admin-gated) already exists and is ignored; no entropy validation on notary_subject_log_secret.
  • HMAC subject hashes are brute-forceable over the national-ID space for anyone holding the (plaintext) secret; no domain separation between client-log and stale-cache hashes; on unresolvable reg_id the code silently hashes the res.partner DB id instead, indistinguishable in the payload.
  • Batch evaluations write no per-subject audit trail (only subject_count); one subject without the configured ID type aborts the whole batch; a mid-batch chunk failure discards already-fetched chunks (re-disclosure on retry); retry_max is dead config and Retry-After on 429 is ignored.
  • Dual cache partitions: data_evaluator writes provider + no params + local TTL (ignoring upstream expires_at) while the notary path writes provider + version params + expires_at. Neither satisfies the other — doubled upstream disclosures, and evidence retained past its upstream expiry.
  • Catalog sync re-activates archived claims and resets operator-set states on every run.
  • spp.notary.claim stores company_id but has no multi-company record rule; note spp.data.value is readable by base.group_user, and notary evidence lands there.
  • Unbounded external input: extra="allow" schemas, no catalog/claim-id length caps, slug collisions crash with a raw IntegrityError, and the raw payload is stored wholesale on the wizard.
  • _external_variable_for_metric runs an uncached spp.cel.variable search on every metric evaluation (hot path, external or not), limit=1 over an OR with no order (nondeterministic), and is not company-scoped — use ormcache.
  • metrics_info from the external path omits base/have/stale keys; a search_count result is computed and discarded on every external metric.
  • 535 lines of pytest-style tests never execute anywhere (no CI pytest job; excluded from the Odoo __init__) and near-duplicate the Odoo-runner suite — keep one.
  • spp_notary_client is missing readme/HISTORY.md; its DESCRIPTION.md is one line (principle asks for structured 25-60 lines); spp_notary_evidence's HISTORY heading level will need checking against the README generator.
  • A docstring claims "session-scoped batching so per-subject calls amortize to a single upstream HTTP request" while the PR's own Remaining gaps says that isn't implemented — align the comment with reality.
  • The description's validation numbers are stale (May): the Odoo suite is now 21/36/591, not 2/23/590.

Suggestions

Add a NotaryServerError for unmapped 5xx; remove the unreachable terminal raise in the retry loop; put error codes, not raw bodies, in details; catch ImportError in the audit wrapper and warn once, not per call; _read_config_value treats 0 as absent; the group_notary_evidence_read group is dead (no ACL/rule/privilege); declare spp_vocabulary directly; _compute_effective_purpose_url and _compute_notary_sensitive_subject_id_type are missing @api.depends; the stale-cache log records a status_code/url implying a call that didn't happen; verify the search_default_group_by_status filter exists in the outgoing-log search view.

What holds up well

The client layer is genuinely Odoo-free; TLS verification stays on and redirects off; no print()/bare except/cr.commit(); the implied_ids audit is clean; Odoo 19 compat is clean (models.Constraint, <list>, Command, chatter); and the tests are real integration tests with non-admin ACL coverage, not mock theatre.

Recommendation

Requesting changes. Criticals 1, 5, 6, and 11 are crashes or data-integrity bugs; 2, 7, 8, 9, 10, and 12 need design-level answers (who may trigger a disclosure, is the purpose trustworthy, is preview a dry run, is cached evidence Data-API-exposed) before this is safe against a real Notary. Critical 4 (the _test_connection change) should be split out of this PR entirely. After that: rebase across the 516 commits coordinated with #272, add the is_data_api_pullable decision, bump spp_cel_domain with HISTORY, and re-run the full validation.

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.

3 participants