Skip to content

Instrument release-admission metrics (#627) - #641

Merged
leynos merged 18 commits into
mainfrom
issue-627-add-bounded-release-admission-observability-metrics
Sep 7, 2026
Merged

Instrument release-admission metrics (#627)#641
leynos merged 18 commits into
mainfrom
issue-627-add-bounded-release-admission-observability-metrics

Conversation

@leynos

@leynos leynos commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

Instrument the limited RFC 0005 release-admission scaffold with bounded JSONL
counters and duration observations. Operators can identify fixed GitHub API,
Git fetch, and evidence-check failures without exposing revisions, run IDs,
paths, URLs, or workflow content as metric labels.

Until a real evidence producer is connected, the read-only scaffold remains
non-blocking. It retains its metrics artefact and job-summary result for every
non-dry-run execution, while recording any admission failure for operators.

Closes #627

Review walkthrough

Validation

  • make check-fmt: passed
  • make typecheck: passed
  • make lint: passed
  • make doc-coverage: passed (99.11%)
  • make test: passed (2,753 tests and doctests)
  • make test-workflow-contracts: passed (110 tests)
  • make markdownlint: passed
  • make nixie: passed
  • CodeRabbit: fresh review queued through comenq (not yet complete)

References

Summary by Sourcery

Instrument the RFC 0005 release-admission scaffold with bounded, artifact-backed observability while keeping publication non-blocking until a real evidence producer is available.

New Features:

  • Add bounded JSONL metrics and trace records for release-admission gate and operation outcomes, errors, and durations.
  • Add a read-only release-admission canary job that publishes workflow summaries and uploads metrics and traces as artifacts.

Bug Fixes:

  • Classify API, fetch, timeout, evidence, mismatch, and unknown failures with fixed fail-closed categories while preserving non-blocking observation mode.

Enhancements:

  • Separate external command adapters from policy classification and enforce closed vocabularies that exclude revisions, run IDs, paths, URLs, and workflow content from telemetry.
  • Document the release-admission observability contract, operator investigation workflow, and transition from observation to enforcement.

Build:

  • Add a dedicated Make target for release-admission runtime tests with pinned Python and test dependencies.

CI:

  • Run release-admission runtime tests as a separate CI check alongside workflow contract tests.

Documentation:

  • Add ADR-020 and developer and user guidance for release-admission observability.

Tests:

  • Add subprocess, failure-path, boundedness, adapter-contract, trace-delivery, and workflow-contract coverage for release-admission telemetry.

Chores:

  • Add shared test fakes, record assertions, and JSONL schema validation for admission metrics and traces.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Implement bounded release-admission observability

  • Instrument the RFC 0005 scaffold with bounded JSONL metrics and traces.
  • Emit gate and fixed-operation metrics with documented labels, durations, and error categories.
  • Exclude revisions, run IDs, paths, URLs, commands, and workflow content from observability records.
  • Support validated observation and enforcement modes.
  • Run the read-only scaffold in observation mode so failures do not block publication.
  • Retain metrics and traces as separate workflow artefacts and report results in the job summary.
  • Define adapter boundaries for GitHub, Git, clock, metrics, workflow output, and trace delivery.
  • Document the contract in ADR-018 and related guides.
  • Add runtime, failure-path, boundedness, validator, property-based, and workflow-contract tests.
  • Add the pinned test-release-admission target to CI.
  • Align the implementation with RFC 0005 and issue #627.

Walkthrough

Add a fail-closed release-admission gate with bounded JSONL metrics and traces. Run it in a non-blocking workflow job, publish its result, retain artefacts, and validate success, failure, timeout, trace-delivery, and identifier-boundedness behaviour.

Changes

Release admission observability

Layer / File(s) Summary
Metric contract and guidance
tests/workflow_contracts/release_admission_metrics.py, docs/adr-018-release-admission-observability.md, docs/contents.md, docs/developers-guide.md, docs/roadmap.md, docs/users-guide.md
Define fixed metric and trace vocabularies, validation rules, export behaviour, operation timeouts, observation and enforcement modes, and operator guidance.
Fail-closed admission gate
.github/scripts/require-release-admission-canaries.sh
Validate configuration, perform bounded Git and GitHub operations, emit metrics and traces, measure durations, and report results through GITHUB_OUTPUT.
Workflow execution and test entry points
.github/workflows/release.yml, .github/workflows/ci.yml, Makefile, tests/workflow_contracts/release_admission_metrics_test.py, tests/workflow_contracts/release_admission_runtime_gate_test.py
Run the canary job, publish results, upload artefacts, preserve publication boundaries, and add a dedicated runtime-test target.
Runtime and boundedness validation
scripts/tests/*release_admission*, tests/workflow_contracts/release_admission_metrics.py
Test success, failure, timeout, trace-sink recovery, fixed labels, finite values, workflow contracts, adapter calls, and identifier boundedness.

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseWorkflow
  participant Gate as require-release-admission-canaries.sh
  participant Git
  participant GitHubAPI
  participant Metrics as JSONL metrics and traces
  ReleaseWorkflow->>Gate: execute admission check
  Gate->>GitHubAPI: resolve commit and workflow run
  Gate->>Git: fetch candidate revision
  Gate->>GitHubAPI: verify freshness and evidence
  Gate->>Metrics: write bounded records
  Gate-->>ReleaseWorkflow: report outcome and error category
Loading

Suggested labels: Issue

Poem

Run the gate and close each door.
Emit fixed metrics, nothing more.
Fetch the commit and check evidence.
Classify failures with fixed values.
Keep traces bounded and clear.

Merge Risk: 🟡 Moderate · up to 72ba3

The admission scaffold can lose operation-level observability on a clock failure, while a hung job may occupy the release workflow for hours. These should be fixed before merge.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 3 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Fail the testing check because the PR adds six documented adapter boundaries, but the runtime tests inject only NETSUKE_RELEASE_ADMISSION_TRACE_SINK. They do not verify `NETSUKE_RELEASE_ADMISSION_GH… Add isolated subprocess tests that inject each documented adapter and assert the adapter receives the expected arguments and bounded records. Add exact trace assertions for every executed operation, gate completion, workflow-output delivery…
Unit Architecture ❌ Error FAIL: Refactor the new admission script before merge. The pull request introduces .github/scripts/require-release-admission-canaries.sh as one unit that performs GitHub and Git operations, reads glo… Split the implementation into explicit units. Make admission queries and evidence decisions return structured results with explicit errors and no metric, trace, file, or workflow-output writes. Keep GitHub and Git access behind narrow injec…
Docstring Coverage ⚠️ Warning Docstring coverage is 62.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 75 functions across 8 files. (7 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Developer Documentation ⚠️ Warning Fail the developer-documentation check because the pull request adds the test-release-admission Make target and a separate CI runtime-test step, but docs/developers-guide.md does not document that… Add a developer-guide subsection or quality-gates entry for make test-release-admission. State that it runs the three release-admission runtime test modules with Python 3.14, pinned pytest==9.0.2 and hypothesis==6.151.9, isolated pyte…
Domain Architecture ⚠️ Warning Separate the release-admission policy from the GitHub and Git protocol details before merge. The new script places external representations inside policy-named functions: resolve_tag_commit builds `… Create explicit adapter functions such as github_resolve_commit(repository, revision) and github_find_workflow_run(repository, revision) that contain the GitHub endpoint paths, jq selectors, and native gh arguments. Create a Git adapt…
✅ Passed checks (10 passed)
Check name Status Explanation
Title check ✅ Passed The title identifies the release-admission metrics change and references the linked issue (#627).
Description check ✅ Passed The description clearly documents bounded metrics, workflow behaviour, tests, documentation, and the non-blocking scaffold boundary.
Linked Issues check ✅ Passed The changes satisfy issue #627: they emit gate and operation metrics, enforce bounded labels and fixed error categories, record durations, validate success and failure paths, document the contract, an…
Out of Scope Changes check ✅ Passed The workflow, runtime tests, trace records, documentation, ADR, and CI changes directly support the release-admission observability objectives. No unrelated code changes are evident.
User-Facing Documentation ✅ Passed Pass this check. The pull-request diff adds a dedicated Release-admission canary section to docs/users-guide.md. It documents the read-only checks, non-blocking observation behaviour, success/fail…
Module-Level Documentation ✅ Passed Pass the module-level documentation check. Every changed Python module has a module docstring. The new support module documents its role in release-admission runtime tests, and the new workflow-contra…
Testing (Unit And Behavioural) ✅ Passed Accept the testing coverage. The runtime tests invoke the production Bash script through /usr/bin/bash, use fake gh and git command boundaries, and inspect real JSONL files and GITHUB_OUTPUT. …
Testing (Property / Proof) ✅ Passed PASS. The change introduces a broad cardinality invariant: revision, run ID, path, and URL values must not enter metric labels or trace fields. `scripts/tests/test_release_admission_metric_boundedness…
Testing (Compile-Time / Ui) ✅ Passed Pass this check. The pull request adds Bash, Python, YAML, and Markdown changes, but no Rust or TypeScript compile-time behaviour. The runtime tests cover the structured JSONL metrics and trace output…
Observability ✅ Passed Pass the Observability check. The changed admission script emits fixed gate and per-operation counters, finite duration observations, and bounded trace records at operation, gate, workflow-output, and…
Full details: Docstring Coverage

Explanation

Docstring coverage is 62.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 75 functions across 8 files. (7 skipped: 7 unsupported.)

Full details: Testing (Overall)

Explanation

Fail the testing check because the PR adds six documented adapter boundaries, but the runtime tests inject only NETSUKE_RELEASE_ADMISSION_TRACE_SINK. They do not verify NETSUKE_RELEASE_ADMISSION_GH_ADAPTER, NETSUKE_RELEASE_ADMISSION_GIT_ADAPTER, NETSUKE_RELEASE_ADMISSION_CLOCK_ADAPTER, NETSUKE_RELEASE_ADMISSION_METRICS_SINK, or NETSUKE_RELEASE_ADMISSION_OUTPUT_SINK. An implementation that ignores those five settings would pass the current tests. The trace test also checks only that the four event names exist and that the final delivery record is bounded. It does not check one operation_complete record per operation or its operation-specific values. The changed script emits these records at lines 127–137, while the normative ADR requires the adapter contracts and ordered trace records. These gaps allow plausible regressions to pass.

Resolution

Add isolated subprocess tests that inject each documented adapter and assert the adapter receives the expected arguments and bounded records. Add exact trace assertions for every executed operation, gate completion, workflow-output delivery, and trace-delivery result, including failure and observation paths. Add a valid evidence-producer fixture if gate-success behaviour remains part of the contract, and assert its success metrics and outputs.

Full details: Developer Documentation

Explanation

Fail the developer-documentation check because the pull request adds the test-release-admission Make target and a separate CI runtime-test step, but docs/developers-guide.md does not document that command, its pinned pytest/hypothesis dependencies, or its CI ordering. The guide does document the admission architecture and workflow through ADR-018 and the observability section, so the failure is limited to the new tooling requirement.

Resolution

Add a developer-guide subsection or quality-gates entry for make test-release-admission. State that it runs the three release-admission runtime test modules with Python 3.14, pinned pytest==9.0.2 and hypothesis==6.151.9, isolated pytest configuration, and that CI runs it after the workflow-contract tests.

Full details: Unit Architecture

Explanation

FAIL: Refactor the new admission script before merge. The pull request introduces .github/scripts/require-release-admission-canaries.sh as one unit that performs GitHub and Git operations, reads global configuration, measures time, formats JSON, writes metric and trace files, writes GITHUB_OUTPUT, mutates global gate state, and applies observation or enforcement policy. run_operation at lines 127-137 executes an operation, invokes timing, emits three records, and updates the gate result. record_gate_result at lines 117-125 combines metric publication, trace publication, workflow output, and trace-delivery policy. duration_seconds at lines 77-82 hides a fallible hard-coded python3 subprocess behind a calculation-looking helper, while clock failures and sink failures are not explicit result values. The adapter environment variables improve substitution, but they do not separate these responsibilities or remove the ambient global state at lines 54-61 and 140-157. The runtime tests cover fake GitHub and Git commands and a trace sink, but do not prove clock, duration, metric-sink, output-sink, or read-only query boundaries. These behaviours are introduced by the pull request; the base branch has no admission script.

Resolution

Split the implementation into explicit units. Make admission queries and evidence decisions return structured results with explicit errors and no metric, trace, file, or workflow-output writes. Keep GitHub and Git access behind narrow injected query or command adapters. Make timing a checked injected clock dependency; remove the hard-coded python3 call from duration_seconds. Split operation execution, classification, metric emission, trace emission, workflow-output publication, and gate-policy selection into separate boundary functions with explicit inputs and outputs. Replace shared mutable variables such as workflow_run_id, operation_error_category, and gate_outcome with returned result data. Handle every adapter failure at the command boundary. Add tests that inject clock and sink failures, verify their explicit error handling, and prove that query execution does not perform publication or persistence side-effects.

Full details: Domain Architecture

Explanation

Separate the release-admission policy from the GitHub and Git protocol details before merge. The new script places external representations inside policy-named functions: resolve_tag_commit builds repos/$repository/commits/$revision and passes the .sha jq expression; fetch_workflow_run builds the Actions REST query and passes another jq expression; and fetch_candidate_revision depends on native git fetch --depth 1 --no-tags origin -- arguments. The declared adapter boundary therefore accepts vendor-specific command arguments instead of translating them into domain-shaped operations. resolve_tag_commit also combines GitHub request construction with the domain mismatch decision. This is a changed-code violation of the required domain/adapter segregation.

Resolution

Create explicit adapter functions such as github_resolve_commit(repository, revision) and github_find_workflow_run(repository, revision) that contain the GitHub endpoint paths, jq selectors, and native gh arguments. Create a Git adapter that exposes a domain-shaped fetch_candidate_revision(revision) operation without exposing native fetch flags to admission policy. Make the policy layer call these adapters and return explicit domain results or fixed domain errors, then classify those results in the observability layer. Pass parsed configuration into the policy functions instead of reading environment-derived globals there. Keep JSONL encoding, file paths, GITHUB_OUTPUT, clocks, timeouts, and sink delivery in infrastructure functions. Add tests that exercise the policy with stubbed domain-shaped adapters and verify that no policy function contains gh, git, REST paths, jq selectors, filesystem paths, or workflow output handling.


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

@sourcery-ai

sourcery-ai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR instruments the RFC 0005 release-admission scaffold with bounded, identifier-safe JSONL counters and duration observations, exports and summarizes the results in GitHub Actions, and fail-closes release publication behind a tested read-only admission job.

Sequence diagram for release admission and publication gating

sequenceDiagram
    participant Workflow as GitHub Actions
    participant Gate as Admission script
    participant GitHub as GitHub API
    participant Git as Git fetch
    participant Evidence as Evidence checks
    participant Artifact as JSONL artifact
    participant Release as Publication job

    Workflow->>Gate: run require-release-admission-canaries.sh
    Gate->>GitHub: resolve_tag_commit()
    Gate->>Git: fetch_candidate_revision()
    Gate->>GitHub: fetch_workflow_run()
    Gate->>Evidence: check_scan_freshness()
    Gate->>Evidence: verify_evidence()
    Gate-->>Workflow: emit gate outcome and operation metrics
    Workflow->>Artifact: upload release-admission-metrics
    alt admission succeeds
        Workflow->>Release: allow publication
    else admission fails or is unknown
        Workflow-->>Release: block publication
    end
Loading

File-Level Changes

Change Details Files
Adds a bounded JSONL metrics emitter to the release-admission scaffold with fixed metric names, label vocabularies, operation timing, and fail-closed error classification.
  • Defines gate, operation, and duration instruments with allowlisted labels and values.
  • Wraps GitHub API, Git fetch, freshness, and evidence operations with success/failure counters and durations.
  • Maps API, fetch, stale, missing, mismatch, and unknown failures without exposing identifiers in labels.
  • Emits an unknown metric record on invalid vocabulary input and records final gate status through workflow outputs.
.github/scripts/require-release-admission-canaries.sh
Integrates the read-only admission gate into the release workflow and makes publication depend on its successful completion.
  • Adds a read-only admission job with pinned checkout and artifact-upload actions.
  • Exports JSONL metrics as a retained workflow artifact and reports the top-level result in the job summary.
  • Blocks the publication job unless the admission job result is success.
.github/workflows/release.yml
Defines and documents the durable bounded-observability contract and operator investigation workflow.
  • Records metric names, label cardinality rules, export behavior, fail-closed semantics, and rejected alternatives in ADR-018.
  • Adds developer guidance for interpreting the summary and downloaded JSONL artifact.
  • Indexes the ADR and updates the release-hardening roadmap.
docs/adr-018-release-admission-observability.md
docs/developers-guide.md
docs/contents.md
docs/roadmap.md
Adds executable and workflow contract coverage for metric shape, failure classification, identifier safety, and release delivery.
  • Validates JSONL records against exact metric and label allowlists.
  • Exercises successful and controlled failure paths through fake GitHub and Git adapters.
  • Uses property-based inputs to verify revisions, run IDs, paths, and URLs never become label values.
  • Pins the admission job permissions, metric artifact, script execution, and publication dependency in workflow tests.
tests/workflow_contracts/release_admission_metrics.py
scripts/tests/test_release_admission_metrics.py
tests/workflow_contracts/release_admission_metrics_test.py

Assessment against linked issues

Issue Objective Addressed Explanation
#627 Emit bounded overall-gate and per-operation release-admission metrics, including operation duration observations with only fixed, non-sensitive labels.
#627 Use a documented, fixed vocabulary for canaries, operations, outcomes, and error categories, with fail-closed categorization for failed admission operations.
#627 Provide workflow export and operator documentation, plus validation covering metric emission, fixed labels and values, error categorization, prohibited high-cardinality labels, and successful and failed gate paths.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos leynos added this to the v0.1.0 milestone Sep 2, 2026
@leynos
leynos marked this pull request as ready for review September 2, 2026 02:03

@sourcery-ai sourcery-ai 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.

Sorry @leynos, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 18 hours and 57 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T09:24:19.548425Z 7204972 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as draft September 2, 2026 12:58
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos

leynos commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix:

Run actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
  with:
    persist-credentials: false
    repository: leynos/netsuke
    token: ***
    ssh-strict: true
    ssh-user: git
    clean: true
    sparse-checkout-cone-mode: true
    fetch-depth: 1
    fetch-tags: false
    show-progress: true
    lfs: false
    submodules: false
    set-safe-directory: true
    allow-unsafe-pr-checkout: false
  env:
    NSC_CONTAINER_REGISTRY: nscr.io/pg9ub7p8bev04
Syncing repository: leynos/netsuke
Getting Git version info
Temporarily overriding HOME='/home/runner/work/_temp/19f91b8a-d767-4ea8-bae9-02bd782d9596' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
/usr/bin/git config --global --add safe.directory /home/runner/work/netsuke/netsuke
Deleting the contents of '/home/runner/work/netsuke/netsuke'
Determining repository object format
Initializing the repository
Disabling automatic garbage collection
Setting up auth
Fetching the repository
Determining the checkout info
/usr/bin/git sparse-checkout disable
/usr/bin/git config --local --unset-all extensions.worktreeConfig
Checking out the ref
/usr/bin/git log -1 --format=%H
a56597adfa4eab165cf071908ddd4f1d5a6d41ca
Removing auth
2s
Run bash .github/scripts/require-release-admission-canaries.sh
  bash .github/scripts/require-release-admission-canaries.sh
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
  env:
    NSC_CONTAINER_REGISTRY: nscr.io/pg9ub7p8bev04
    GH_TOKEN: ***
    NETSUKE_RELEASE_ADMISSION_METRICS_FILE: /home/runner/work/_temp/release-admission-metrics.jsonl
From https://github.com/leynos/netsuke
 * branch            a56597adfa4eab165cf071908ddd4f1d5a6d41ca -> FETCH_HEAD
Error: Process completed with exit code 1.

@coderabbitai

This comment was marked as resolved.

@wafflecat-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]

This comment was marked as resolved.

@leynos
leynos marked this pull request as ready for review September 4, 2026 09:20

@sourcery-ai sourcery-ai 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.

Sorry @leynos, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 5 days and 11 hours by commenting @sourcery-ai review. Upgrade to get a review now.

codescene-access[bot]

This comment was marked as outdated.

@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: 7204972b5f

ℹ️ 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 thread .github/scripts/require-release-admission-canaries.sh Outdated
@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]

This comment was marked as resolved.

@leynos

leynos commented Sep 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai please addapt the following issue text for netsuke's Python infrastructure and raise a GitHub issue against leynos/netsuke:

`episodic` is the only repository in this group whose lint gate has no
docstring-coverage stage. `make lint` runs Ruff, Pylint, `df12-python-lints`,
the future-annotations pass, `ambrleaks`, and Skylos, but nothing enforces
docstring coverage, and `interrogate` appears in neither the `Makefile` nor
`pyproject.toml`.

`leynos/lading`, `leynos/cuprum`, and now `leynos/femtologging` all gate their
production package with `interrogate --fail-under 100`.

## Current state

Measured with `interrogate==1.7.0`, with no gate in place:

| scope | coverage | missing |
| --- | --- | --- |
| `episodic` (production) | 93.5% | 136 of 2105 |
| `tests` + `scripts` + `alembic` | 90.4% | 268 of 2793 |

The production package is close enough to 100% that adopting the gate is mostly
a matter of closing 136 definitions, not a restructuring exercise.

## Proposed work

1. Close the 136 production gaps, then add the tier to `lint` in the estate's
   established form:

   ```make
   INTERROGATE_VERSION ?= 1.7.0
   INTERROGATE = $(UV_ENV) $(UV) tool run --from 'interrogate==$(INTERROGATE_VERSION)' \
     interrogate --fail-under 100
   ```

   Pin the version: an unpinned interrogate can change the coverage verdict with
   no repository change.

2. Then triage the 268 non-production gaps as a second step, following whatever
   convention the sibling issues settle for nested closures and BDD step
   functions.

Watch for one trap found while adopting this in `femtologging`: `@typ.overload`
stubs cannot carry docstrings, because Ruff `D418` forbids them, and interrogate
1.7.0 only recognises the literal `typing.overload` and `overload` spellings, so
`--ignore-overloaded-functions` does not see the `typ.` alias that these repos'
import conventions require. A targeted `--ignore-regex` is the available
workaround; Ruff's `undocumented-public-function` still guards the real
implementation, so no coverage is actually lost.

## Context

Raised alongside equivalent issues for `femtologging`, `cuprum`, and `lading`,
so the estate converges on one rule for what "documented" means. This repository
needs the extra first step of adopting the tool at all.

codescene-access[bot]

This comment was marked as outdated.

@leynos

leynos commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message in a code block that I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

Complex Method

scripts/tests/test_release_admission_metric_boundedness.py: test_identifiers_never_become_metric_labels

What lead to degradation?

test_identifiers_never_become_metric_labels has a cyclomatic complexity of 9, threshold = 9

Why does this problem occur?

A Complex Method has a high cyclomatic complexity. The recommended threshold for the Python language is a cyclomatic complexity lower than 9.

How to fix it?

There are many reasons for Complex Method. Sometimes, another design approach is beneficial such as a) modeling state using an explicit state machine rather than conditionals, or b) using table lookup rather than long chains of logic. In other scenarios, the function can be split using EXTRACT FUNCTION. Just make sure you extract natural and cohesive functions. Complex Methods can also be addressed by identifying complex conditional expressions and then using the DECOMPOSE CONDITIONAL refactoring.

Helpful refactoring examples

To get a general understanding of what this code health issue looks like - and how it might be addressed - we have prepared some diffs for illustrative purposes.

SAMPLE

# complex_method.js
 function postItem(item) {
   if (!item.id) {
-    if (item.x != null && item.y != null) {
-      post(item);
-    } else {
-      throw Error("Item must have x and y");
-    }
+    // extract a separate function for creating new item
+    postNew(item);
   } else {
-    if (item.x < 10 && item.y > 25) {
-      put(item);
-    } else {
-      throw Error("Item must have an x and y value between 10 and 25");
-    }
+    // and one for updating existing items
+    updateItem(item);
   }
 }
+
+function postNew(item) {
+  validateNew(item);
+  post(item);
+}
+
+function updateItem(item) {
+  validateUpdate(item);
+  put(item);
+}
+

@coderabbitai

This comment was marked as resolved.

@leynos

leynos commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat o11y, code safety, documentation and validation coverage as in scope).

❌ Failed checks (2 errors, 3 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Fail the testing check because the PR adds six documented adapter boundaries, but the runtime tests inject only NETSUKE_RELEASE_ADMISSION_TRACE_SINK. They do not verify `NETSUKE_RELEASE_ADMISSION_GH… Add isolated subprocess tests that inject each documented adapter and assert the adapter receives the expected arguments and bounded records. Add exact trace assertions for every executed operation, gate completion, workflow-output delivery…
Unit Architecture ❌ Error FAIL: Refactor the new admission script before merge. The pull request introduces .github/scripts/require-release-admission-canaries.sh as one unit that performs GitHub and Git operations, reads glo… Split the implementation into explicit units. Make admission queries and evidence decisions return structured results with explicit errors and no metric, trace, file, or workflow-output writes. Keep GitHub and Git access behind narrow injec…
Docstring Coverage ⚠️ Warning Docstring coverage is 62.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 75 functions across 8 files. (7 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Developer Documentation ⚠️ Warning Fail the developer-documentation check because the pull request adds the test-release-admission Make target and a separate CI runtime-test step, but docs/developers-guide.md does not document that… Add a developer-guide subsection or quality-gates entry for make test-release-admission. State that it runs the three release-admission runtime test modules with Python 3.14, pinned pytest==9.0.2 and hypothesis==6.151.9, isolated pyte…
Domain Architecture ⚠️ Warning Separate the release-admission policy from the GitHub and Git protocol details before merge. The new script places external representations inside policy-named functions: resolve_tag_commit builds `… Create explicit adapter functions such as github_resolve_commit(repository, revision) and github_find_workflow_run(repository, revision) that contain the GitHub endpoint paths, jq selectors, and native gh arguments. Create a Git adapt…

@coderabbitai

This comment was marked as resolved.

Record the bounded metric vocabulary, fail-closed classification, JSONL
workflow artefact export, and operator workflow for the release-admission gate.
Index the ADR and link the observability work from roadmap section 9.4.
Point the implementation references at the release-admission test modules
present in the workflow-contract and script test suites.
Emit bounded JSONL counters and operation latency observations from the
release-admission scaffold. Retain the records as a workflow artefact and
surface the gate outcome in the job summary before publication can proceed.

Validate fixed labels and error categories with subprocess, property, and
workflow-contract tests.
Load the workflow-contract validator without changing the global Python
search path, and narrow the workflow dependency before inspecting it.

Terminate the fetched revision options explicitly so generated test values
cannot be interpreted as Git options.
Fail the gate when its final metric cannot be written, and bound every
GitHub or Git command with a validated timeout category.

Move runner-only paths to step environments, preserve dry-run artefact
behaviour, and retain the scaffold as non-blocking until a real evidence
producer is available.

Expand the metric, workflow, and boundedness contracts, and document the
operator-facing behaviour.
Cover mismatched revisions, absent workflow evidence, and elapsed timeout
metrics so the bounded emission contract remains enforced.
Extract narrow validation and workflow-contract assertions to satisfy the
configured CodeScene complexity and method-size limits without changing the
bounded metric contract.
Record unavailable evidence as a bounded admission failure while allowing the
RFC 0005 scaffold workflow to complete in observation mode. Tighten timeout
cleanup and cover the configuration and workflow contracts.
Reject synthetic freshness as missing evidence while retaining its
non-blocking observation result. Provision the required timing runtime and
cover targeted workflow-run and configuration failure boundaries.
Align the release-admission job with main's GitHub-hosted runner policy
so actionlint recognises the workflow after the rebase.
Gate the runtime contract in pull-request CI and isolate external Bash
effects behind narrow adapters. Export bounded trace records alongside
existing metrics without changing observation-mode publication.
Preserve bounded operation results when the monotonic clock fails, and
strengthen release-admission runtime and workflow-contract coverage.
Preserve the empty-run distinction and narrow fake-command values so the
review repairs satisfy the repository's Python quality gates.
Isolate external protocol effects and bounded policy decisions from gate
orchestration and reporting. Exercise every adapter and complete trace
hand-off while documenting the dedicated runtime gate.
Extract independent metric, output, trace, and sink assertions so the
contract tests remain below the CodeScene complexity threshold.
Extract the boundedness assertions and consolidate invalid configuration
coverage without weakening the gate contracts. Preserve both ADR decisions
after `main` assigned ADR-018 to Ninja option handling.
@leynos
leynos force-pushed the issue-627-add-bounded-release-admission-observability-metrics branch from b2d5bd1 to 02e3ba0 Compare September 6, 2026 22:13
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@codescene-access codescene-access 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.

No quality gates enabled for this code.

@leynos
leynos merged commit 5fda1e6 into main Sep 7, 2026
21 checks passed
@leynos
leynos deleted the issue-627-add-bounded-release-admission-observability-metrics branch September 7, 2026 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add bounded release-admission observability metrics

4 participants