Skip to content

feat(reporting): expose durable webhook activity - #1183

Merged
bokelley merged 8 commits into
mainfrom
conductor/reporting-webhook-activity-1168b
Sep 23, 2026
Merged

bokelley merged 8 commits into
mainfrom
conductor/reporting-webhook-activity-1168b

Conversation

@bokelley

@bokelley bokelley commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Reporting webhook attempts become durable, account-scoped activity that buyers can read through list_accounts(include_webhook_activity=true). A worker crash retains an honest pending reservation; a retry keeps the notification, prepared body and idempotency key while allocating the next HTTP attempt.

Refs #1168. This is the #1168B activity slice following merged #1178. Status notification projection, fingerprint deduplication and clock sweeps remain #1168C.

  • Reserve immediately before HTTP after preparation and the final lease fence. Only the matching pending reservation can record a terminal outcome. Uncertain commits prevent HTTP or parent acknowledgement as appropriate; retained heads preserve attempt numbering after retention.
  • Bind activity reads to the account and canonical principal before applying a per-account limit of 1–200 rows. Return newest-first with stable ties. Retain pending rows and counters; purge terminal activity only strictly beyond the 30-day completed-at floor.
  • Require trusted registry, authentication and signing identities to agree. Optional handler mounting preserves legacy account envelopes, credential scrubbing and existing store protocols. Forward the request's exact account filter alongside status, sandbox and pagination. Omit unsupported or unrequested activity; return an empty list for supported, requested activity with no records.
  • Redact display URLs and enforce the 8,192-character subscription bound on canonical encoded URLs. Keep diagnostics closed and protect concurrent transport logging. Durable capabilities validate the mounted writer, store and projector; memory components do not establish durable activity support.

The sixth packaged migration adds B tables, indexes, constraints and guard functions without rewriting or backfilling A evidence. Required-object validation permits unrelated adopter objects while strictly checking every required object's fingerprint and enabled state. The typed example and migration guide cover registration, mounting, readiness, draining and shutdown.

Activation order: migrate while A serves its existing configuration, then drain or replace A workers before enabling B activity and canonical URL-principal subscriptions. A workers do not record activity and A registration rejects URL principals; mixed A/B workers cannot establish complete activity coverage.

Current-main composition

Original feature 198d50e61c74fb82aedbf2c77e06a0e200b91db6 is preserved. Ordinary merge bddbf1c6f9077939b4f67e98bac0cd8054431722 has ordered parents [198d50e6, 17ee407a], where 17ee407ae3978c8a2bb54437287afbf9dafb8130 is the actual merged #1178 main. Corrective child 46191d308ad949bff21696f04c4b4892e0f6884a has tree 8ab1d6f67ada5f381203a77c2c6412a6fe354b9e. Two further ordinary children preserve that ancestry: 655e9c27742faec089259129cfc47f8698f7e1ad separates operational test calls from assertions; 03c49f178d1d51857cdb7afb06bc601bc770b0ca distributes the PostgreSQL workload. Three further ordinary children restrict the PG aggregate token, document two injected test-exception handlers and restrict the PG execution tokens. Current head is d0d74b9c90c3eea1758da5e794c33e4f7a6fc67e, tree e70551bc2b5c7cc7e69ee7a910f746e749f72b11. All original 31 feature paths remain; the complete diff is 31 files, +5818/-446. No parent was amended, rebased or rewritten.

The schema-inspector conflict retains B's original per-object implementation byte-for-byte. Each named object is hashed independently, so cross-row database collation no longer enters its fingerprint. Main's ledger DDL, settling, currency, evidence, strict checkpoint damage controls and previously corrected test harness remain intact.

The five-file corrective child (+94/-31) addresses the observed composition failures:

  • Add exactly 11 checkpoint objects observed from the fresh migrated catalog: its table, five columns, three constraints and two indexes. All 453 existing manifest entries remain identical, with zero removals or fingerprint replacements. The new manifest has 464 objects; the validator is unchanged and strict.
  • Move nine optional PostgreSQL import statements inside existing fixture context managers across six tests / sixteen parameterized cases. Assertions and imported symbols remain unchanged. Base installations reach their intended skips; PostgreSQL runs execute the cases.
  • Adapt the inherited aggregate-index regression to B's independently keyed index fingerprints. The expected serialization remains independent of the production digest helper and retains quoted-uppercase/lowercase keys, partial predicates and validity/readiness/liveness flags.
  • Pin both the rolling test and its CI fetch to integrated A commit 17ee407a, including its checkpoint and locale-readiness corrections. The guide explicitly identifies this predecessor. The older 21bf443e subprocess failures remain retained; current-predecessor greens do not qualify that historical snapshot or erase its locale-sensitive contract.

Test and CI follow-up

The reviewed test/workload follow-up 46191d30..03c49f17 is five files, +150/-96, patch SHA256 eec126799029a678d2364665919793c55e72af791d788a8383a74200313ff14f. SDK implementation, required manifest, dependencies and documentation are identical to 46191d30.

  • Hoist 42 operational awaits before their result assertions across three test files, including eight awaits in two raw subprocess source strings. Preserve every receiver, argument, expected result and surrounding statement order. An inverse AST check reconstructs the complete parent source: 21 bare awaits, 13 comparisons with a constant, seven negations and one callback guarded by its original non-None assertion. Pure reads and cancellation joins inside pytest.raises remain unchanged.
  • Explain the expected poll timeout and the distinct SIGKILL already-exited race. Keep the existing SIGTERM comment, both escalation stages, pipe drain/reap behavior and every timeout unchanged. The five sole-Ellipsis interface declarations, two cancellation joins and pure delivery-read/decode assertion were source-adjudicated as false positives. Historical discovery-cost thread 9rLB was already resolved with a separate fix(reporting): cache schema proofs and retain safe receipt diagnostics #1191 follow-up; its fix remains absent here and receives no credit on this PR.
  • Split PG execution into core (1,485 cases) and process (seven cases), each on a separate fresh service with the existing 15-minute job ceiling. Core excludes the entire process-matrix file; process runs that whole file, so future cases in it remain partitioned. The original selected scope is unchanged. Actual collection proves an exact disjoint union of all 1,492 identities. Fail-fast is disabled. A strict aggregate preserves the existing Postgres conformance tests (Postgres 16) required name and accepts only success from the complete matrix, failing for cancellation, failure, skips or an empty result. CI expands from 16 to 18 jobs. This increases runner allocation, not individual execution deadlines.

Original ordinary CI remains cancelled. Run 35832702909, attempt 1, PG job 107088786196 checked out merge 384544f9. Its original log printed 1492 passed, 1 warning in 840.82s at 07:52:48Z, then the job exceeded its 15-minute maximum and ended CANCELLED. The raw log SHA256 is f7d270a2d62cd6612b9394e35c1eb5f818fc35af3d220c83ff007f2fb32bcd16. The printed result is retained alongside the cancellation; it is not passing CI. The original guard closed NOT_READY with two open documentation findings. No workflow rerun, cancellation, timeout increase or waiver was used.

Local test-only child 655e9c27 passed the two base-installation files (52 passed / 85 intended optional-PG skips, 16.259s under 180s) and all three changed test files on fresh PG16.14/libc en_US.utf8 (143 passed / zero skips, 155.485s pytest / 168.396s outer under 600s). Both runs and clean teardown retain their actual child identity.

Local executions on predecessor 03c49f17 / tree 56c58c28 used separate fresh PostgreSQL 16.14/libc en_US.utf8 clusters and CPython 3.12.14. Each pytest invocation retained a 900-second ceiling:

Lane Result JUnit suite / outer time Original stdout SHA256
core 1485 passed, zero failures/errors/skips; one expected legacy-HMAC warning 309.494 s / 322.897 s 89db5fc6948576b2f76453493020185c43f7a249a34b446c3f298665b3c6ddcd
process 7 passed, zero failures/errors/skips 308.073 s / 321.689 s ec0dae9d47efb7a2a4b026d79735a23c13ed745e0da890fef6809c5b8b9cba52

Printed pytest times were 309.50 seconds for core and 308.65 seconds for process; the table retains the separate JUnit suite times. Both clusters had zero remaining clients, their databases were dropped, and normal shutdown completed. These are local execution results; fresh CI must qualify checkout, dependency/service setup, tests and teardown within each whole-job 15-minute limit. The original CI process-file result boundary spanned about 381 seconds, motivating the partition without claiming isolated per-case timing or transferring a cancelled result.

Static verification also exercised the aggregate success/failure/cancelled/skipped/empty branches. Private helper errors are retained separately: shell continuation parsing, a URL-absent collection that intentionally omitted 130 PG-module cases, and an attempted comparison against GitHub-masked synthetic parameter labels. The corrected URL-present collections are 1,492 / 1,485 / seven with zero overlap or missing cases; no test body was executed during collection. The masked original log cannot establish equality of unredacted case IDs. These are validation-helper limitations, not SDK failures or transferred CI results.

Narrow permissions and test-comment correction

The final append over 03c49f17 touches two files, +5/-0, patch SHA256 989b4fb459db1f156ff46140c148d72f95290648b3b9e37a1cbef586091de2b5. The three commits are strictly linear: d0d74b9c → 312985b0 → 040639ff → 03c49f17.

  • Set permissions: {contents: read} on both PG execution lanes for checkout and the pinned predecessor fetch. Set permissions: {} on their aggregate, which reads the matrix result without repository access. These address both genuine CodeQL annotations on exact03; its successful check conclusion did not mean zero alerts. All other parsed workflow values, commands, services, lane dispatch, aggregate conditions and deadlines are identical to03. Other inherited workflow permission gaps remain outside this correction.
  • Explain the two function-local ContextExitError handlers in the logging test: one permits outer-context checks after the injected inner exit, and the other permits post-exit restoration checks after the injected outer exit. Full Python AST, including every constant, is identical. The SDK does not raise this test sentinel; both handlers deliberately let the subsequent assertions execute.

Static comparison and normal commit hooks passed. No SDK/test execution was added for this permissions/comment-only delta. Fresh ordinary CI, complete scanner-output and review-thread readback, and bounded delta review must bind this head; no03 result transfers.

Exact03 original CI completed successfully, with ordinary findings retained. Run 35835555465, attempt 1, completed all 18 jobs successfully. Both execution jobs checked out merge c2e1aba0: core passed 1,485 tests with one warning in 448.16 seconds, and process passed seven in 283.58 seconds. Their full job lifecycles were 531 and 353 seconds, respectively, within the unchanged 15-minute ceilings. The required aggregate succeeded with PG_RESULT: success. Raw lane log SHA256 values are eca061db9fb758dfa2b8cc762541d9f95dbe5b4dae393e0626d05d42deb4818f and b375983fbd957df8b558a7ee7ca2e7d82fd36d89fb432f54367c28480e16942d; aggregate c73540ecf27390791dcc87f8955ca005373a5635028d09da7960ed9d62367ca8.

The exact03 CodeQL check succeeded while reporting two genuine permission alerts; two test-handler documentation threads also remained open before this append. The original03 results and findings are preserved in guard disposition 37dcda59bcffe5e5be719cb660cdd321b498592fdf5e2c0f0e92c28cd0a619cb, closed NOT_READY with 14 threads / 11 resolved / three open. The earlier461 job remains CANCELLED. Neither head's execution or review is attributed to this final child.

Preserved composition validation

Local invocation Actual result Pytest time / ceiling
Base installation without PostgreSQL extras, activity migration file 33 intended skips, 0 failures 13.44 s / 180 s
C database, migration/readiness/activity selection 84 passed, 0 skips 67.62 s / 600 s
ICU en-US database, same selection 84 passed, 0 skips 66.87 s / 600 s
libc en_US.utf8 database, full CI PostgreSQL selection 1492 passed, 0 failures/errors/skips; 1 expected legacy-HMAC warning 596.92 s / 900 s

The full PostgreSQL invocation took 610.29 seconds including launcher overhead. Its original stdout SHA256 is e306acdc526f722c784ea5fce0501e13e4122c45607d12f3a2722f98ad1a8048. Both actual-binary rolling directions passed in all three database regimes. Wheel/sdist and crash/restart tests are included in that full selection. Final database clients were empty; the fresh cluster stopped normally.

Execution provenance: these local runs used retained child 2c5d284f9f2213c1c0c30e3a32fba18fcb664173, tree 8ab1d6f67ada5f381203a77c2c6412a6fe354b9e. Published corrective commit 46191d30 has exactly the same tree and an empty source diff relative to that local execution identity. A prepublication check caught root's rejected merge(reporting): ... commit title. Root preserved that unpublished lineage, made a fresh ordinary merge from the original feature and the same main using the accepted Merge branch ... title, and appended the identical corrective patch. No commit was amended, reset, rebased or force-pushed; the validator was not changed. Local logs retain their actual execution head; fresh CI and independent review must bind the final published head.

The required-correct controls ran before correction on unchanged composed parent 71b330ab: base-only activity migration reported 16 failed / 17 skipped (optional-driver imports before fixture skipping); PostgreSQL reported 14 failed / 70 passed. Those include six historical manifest equalities, four checkpoint damage refusals, exact-manifest equality, the inherited aggregate-index key, and two historical-A subprocess exits. The subprocess helper discarded their stderr, so those exits alone do not establish a lower-level cause. Their original streams remain unchanged.

Fresh C, libc en_US.utf8 and ICU en-US catalogs each match all 464 objects with strict readiness. The recorded local executions bind the source tree above, CPython 3.12.14 and PostgreSQL 16.14. The C/ICU focused selections retain the 600-second limit; the broader libc CI PostgreSQL selection retains 900 seconds. Counts are per invocation, not additive. Ordinary CI and independent composition review must bind this new published head and its actual main composition; no original-head CI or review result transfers.

Earlier extensive local and independent results on 198d50e6 remain historical and are preserved in the original PR body/evidence. They are not labelled as execution on this composition. No installed main artifact, registry release, published-byte pin, full #1199 acceptance or TS calendar/interop clearance is claimed.

Remaining scope and risks

  • HTTP and database commits cannot atomically prove peer receipt. Uncertain attempts remain pending; receivers must deduplicate. Pending orphans and sequence heads are retained indefinitely.
  • Required-object validation deliberately permits extra adopter DDL. Extra triggers, rewrite rules, row-level security policies and reloptions can affect behavior without changing a required fingerprint. The unrelated-adopter-object tests preserve this explicit feature trade-off.
  • Canonical BuyerAgent URL principals still rely on verified middleware. Their validator does not restore all credential-shape screens formerly applied by principal_reference; principal IDs are omitted from the wire projection. This existing defense-in-depth limitation remains separate.
  • Capability validation queries the live catalog; activity projection uses one connection/transaction per visible account. A store failure fails the account read rather than misrepresenting support by omitting activity.
  • The original source was based on the older A branch. This composition targets actual main and requires fresh ordinary CI on the current head, including both 15-minute PostgreSQL execution lanes and their strict aggregate. Neither the historical A pin nor an older CI result is substituted for it.

@gitguardian

gitguardian Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@bokelley
bokelley added this pull request to stack #1184 September 16, 2026 13:57
Comment thread src/adcp/decisioning/handler.py

@aao-secretariat aao-secretariat 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.

Ladon verdict: Approve

Approve — #1168B durable webhook-activity slice reviewed clean.

The change is additive throughout: no public export removed or renamed, new worker/server kwargs are keyword-only and default to None under a feat: prefix, no hand-edits to generated code, no credential path through ctx_metadata, and forward-compat on discriminated unions is intact. The reviewer covered the largest new files (activity.py, _activity_pg.py), the _schema.py manifest rewrite, the additive SQL migration/guards, and the reservation/ACK fail-closed windows.

Medium findings

  • src/adcp/decisioning/handler.py:2062 — get_adcp_capabilities re-runs a full ~450-object schema catalog validation per discovery call when supports_webhook_activity is claimed (perf, non-blocking).

Decision path: no critical/high findings (row 1 n/a). gated_paths is false (row 2 n/a). high_risk is true but all high-risk entries are (modified) with no medium finding on those files — the single medium is on handler.py, but it is a perf/LLM-context scope concern, not a data-loss/schema/infra category, so rows 3–5 do not fire. No prior escalation (row 6 n/a). No no-auto-approve team match (row 7 n/a). Only one medium finding, below the three-medium threshold (row 8 n/a). Falls through to row 9 → approve.

@bokelley
bokelley force-pushed the conductor/reporting-webhook-activity-1168b branch from 2b6a09a to d4c10cf Compare September 16, 2026 14:10

@aao-secretariat aao-secretariat 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.

Ladon verdict: Approve

Approve — durable webhook activity slice, subsequent pass.

The reviewer read every changed source file and surfaced no critical, high, or medium findings. Key invariants checked and holding:

  • Worker: reservation-before-HTTP crash honesty and bounded timeouts (worker.py)
  • Fail-closed durable-only capability gating (support.py / _capabilities.py)
  • URL sanitization and identity-agreement guards
  • Additive/immutable SQL triggers and per-object schema-manifest rewrite
  • Forward-compat, import-layering, credential (ctx_metadata), and CI-gate invariants intact
  • Additive semver signal correctly carried on the feat: commit

Decision-table walk:

  • Rows 1–2: no critical/high findings; gated_paths is false and review_decision is APPROVED — no gate applies.
  • Row 3: no (deleted) high-risk reasons (all (modified)).
  • Rows 4–5: no medium findings, so no medium+sensitive or high-risk-modified+medium trigger.
  • Row 6: prior decision was approve, not escalate — sticky rule N/A.
  • Row 7: no no-auto-approve team match.
  • Row 8: fewer than three medium findings (zero).
  • Row 9: approve.

high_risk is true only from (modified) decisioning/server files, and the reviewer found no medium-or-higher concerns on them, so the modifications are presumed safe. Prior run also approved with no findings; this pass confirms the net state remains clean.

Persist fenced HTTP attempt reservations and outcomes, project bounded activity
for visible accounts and the canonical authenticated consumer, and validate
durable capability wiring. Preserve legacy account/store interfaces and require
the additive migration and A-worker activation barrier before enabling activity.

Bound the subscription URL on its canonical form so a registration that would
only fail after percent-encoding is rejected with a secret-free diagnostic
rather than quarantining every later expansion.

Bundle the deterministic required-object manifest and cover migration, installed
wheel/sdist compatibility, process crashes, concurrent transport logging, and
the existing reviewed-A binary. Keep status projection and clock sweeps for C.

Refs #1168

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bokelley
bokelley force-pushed the conductor/reporting-webhook-activity-1168b branch from d4c10cf to 198d50e Compare September 16, 2026 14:28
aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Sep 16, 2026

@aao-secretariat aao-secretariat 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.

Ladon verdict: Approve

Approve — clean subsequent pass, no blocking or medium findings.

This is a subsequent review on top of a prior clean approve. The delta since the last approved head is a single test-only change: a scanner-safe JWT-shaped sanitizer fixture in tests/conformance/reporting/test_reporting_activity_projection.py that constructs an inert 8-byte ES256 JWT at runtime and asserts shape plus constant redaction. No production code changed in this delta.

The previously flagged sanitize_activity_url concern is closed in this head — routing.py now bounds and stores the httpx-canonical subscription URL with idempotent re-validation coverage.

High-risk flag: true, but only (modified) reasons on src/adcp/decisioning/** and src/adcp/server/**. Per the change-kind rules, modifications with no medium-or-higher findings are presumed safe; there is no deletion and no medium finding to trigger escalation rows 3/5.

Gate checks: gated_paths is false; review_decision is APPROVED; no no-auto-approve team match. No critical/high/medium findings.

Decision table: rows 1–8 do not fire (no findings, no deletions, no team gate, prior decision was approve not escalate). Falls through to row 9 → approve.

Comment thread tests/conformance/reporting/test_reporting_webhook_activity.py
@bokelley
bokelley removed this pull request from stack #1211 September 23, 2026 07:12
Base automatically changed from conductor/reporting-transactional-outbox-1168a to main September 23, 2026 07:13
@bokelley
bokelley dismissed aao-secretariat[bot]’s stale review September 23, 2026 07:13

The base branch was changed.

Comment thread src/adcp/reporting/outbox/activity.py
Comment thread src/adcp/reporting/outbox/activity.py
Comment thread src/adcp/reporting/outbox/activity.py
Comment thread src/adcp/reporting/outbox/activity.py
Comment thread examples/reporting_webhook_activity.py
Comment thread tests/conformance/reporting/test_reporting_activity_migration.py
Comment thread tests/conformance/reporting/test_reporting_webhook_activity.py
Comment thread examples/reporting_webhook_activity.py Fixed
aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Sep 23, 2026

@aao-secretariat aao-secretariat 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.

Ladon verdict: Approve

Approve — subsequent pass on PR #1183, clean.

This is a follow-up to a prior clean approve (head 198d50e). The delta since then is dominated by main-merge churn (already-reviewed #1178 reporting service/outbox work and the TargetingOverlayInput export). The genuinely authored surface is the five-file corrective child 46191d3: 11 checkpoint manifest entries in required_schema.json, CI/test predecessor repins to 17ee407, optional-driver import relocations into fixture context managers for correct skip ordering, and a new independent index-fingerprint regression test.

All corrective changes are manifest/CI/test-only and internally consistent. The reviewer surfaced no Critical/High/Medium findings, and no prior blockers existed to re-evaluate.

Decision-table walk:

  • Row 1 (critical/high): no findings — skip.
  • Row 2 (gated_paths): false — skip.
  • Row 3 (high-risk deleted): high_risk is true, but all three high-risk reasons are (modified), none deleted — skip.
  • Row 4 (medium + data-loss/schema/infra): no medium findings — skip.
  • Row 5 (high-risk modified + medium): high-risk modified files exist, but no medium finding — skip.
  • Row 6 (sticky escalate): prior decision was approve, not escalate — skip.
  • Row 7 (no-auto-approve team): no team match — skip.
  • Row 8 (≥3 medium): zero medium — skip.
  • Row 9: approve.

The high-risk flag on decisioning/server files is a look-closer signal only; those files are modified but carry no reviewer-flagged concern, so the modification is presumed safe. Falls through to row 9 = approve.

Comment thread .github/workflows/ci.yml Fixed
Comment thread tests/conformance/reporting/test_reporting_transport_logging.py Fixed
Comment thread tests/conformance/reporting/test_reporting_transport_logging.py Fixed
aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Sep 23, 2026

@aao-secretariat aao-secretariat 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.

Ladon verdict: Approve

Approve — clean pass on the delta.

Checked:

  • CI pg-conformance job split into a fail-fast:false core/process matrix with a required-gate aggregator that reuses the prior job name and fails closed unless every lane succeeds; coverage union preserved and unknown lanes fail-closed.
  • Test files mechanically hoist side-effecting awaits out of assert expressions (-O-safe) with polarity and ordering intact; one example gains a clarifying comment.
  • high_risk is true only from (modified) matches on decisioning/handler.py, decisioning/serve.py, and server/principal.py — no medium-or-higher findings on those files, so the modifications are presumed contract-preserving (row 5 does not fire).

Decision-table walk: no critical/high findings (rows 1, 6 clear); gated_paths is false (row 2 N/A); no (deleted) high-risk reason (row 3 N/A); no medium findings in any escalation category (rows 4-5 N/A); no no-auto-approve team match (row 7 N/A); fewer than three medium findings (row 8 N/A). Falls through to row 9.

Prior decision was approve; nothing to re-surface. No blocking findings.

@aao-secretariat aao-secretariat 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.

Ladon verdict: Approve

Approve — clean delta pass since prior approve.

Two changes since the last approved head (03c49f1):

  • .github/workflows/ci.yml adds correct least-privilege permissions blocks (contents: read on the pg-conformance checkout job, permissions: {} on the fan-in summary job).
  • The reporting transport-logging test gains two comments documenting the intentional nested ContextExitError pass handlers.

No behavior change, no public-surface/wire/generated-code impact. No Critical, High, or Medium findings. high_risk is true only because modified files match src/adcp/decisioning/** and src/adcp/server/** globs, but the reviewer found no medium-or-higher concerns on them, so the modifications are presumed safe (not escalation-worthy on the flag alone). No gated paths, no no-auto-approve team match. Prior decision was already approve.

Decision rules top-down: rows 1–8 do not fire → row 9 approve.

@bokelley
bokelley merged commit 0f34c66 into main Sep 23, 2026
29 checks passed
@bokelley
bokelley deleted the conductor/reporting-webhook-activity-1168b branch September 23, 2026 08:51
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