Skip to content

fix(browser_harness): deduplicate env loading and add repo automation#473

Open
giattijunior wants to merge 10 commits into
browser-use:mainfrom
giattijunior:nm-smoke
Open

fix(browser_harness): deduplicate env loading and add repo automation#473
giattijunior wants to merge 10 commits into
browser-use:mainfrom
giattijunior:nm-smoke

Conversation

@giattijunior

@giattijunior giattijunior commented Jun 25, 2026

Copy link
Copy Markdown

What Changed

  • Reworked src/browser_harness/admin.py and src/browser_harness/daemon.py to reuse the shared _load_env helper, removing duplicated env-loading code and fixing the admin loader shadowing issue.
  • Added repo automation under .github/ with Renovate config/workflow, dependency review support, and a dupehound workflow for duplicate detection in CI.
  • Updated repo automation docs and gate config in README.md, agent-workspace/SMOKE.md, AGENTS.md, and .no-mistakes.yaml to match the new automation flow.

Risk Assessment

⚠️ Medium: Mudancas de app sao pequenas, mas os novos workflows de CI introduzem regressao de enforcement e enfraquecem a cadeia de supply-chain do pipeline.

Testing

Exercitei a suíte unitária relevante via uv run, validei o entrypoint real com ./browser-harness --doctor e gerei evidência parseando os novos workflows/configs; o resultado foi limpo para a mudança proposta, com o doctor mostrando apenas ausência de daemon/conexão de browser ativos neste ambiente de teste.

Evidence: browser-harness doctor transcript
browser-harness doctor
  platform          Darwin 27.0.0
  python            3.12.13
  version           0.1.3 (pypi)
  latest release    0.1.3
  [ok  ] chrome running
  [FAIL] daemon alive — see install.md
  [FAIL] active browser connections — 0
  [FAIL] Browser Use cloud auth — optional: browser-harness auth login
Evidence: workflow and renovate config summary
{
  "no_mistakes_agent": "agent: codex",
  "renovate": {
    "baseBranchPatterns": [
      "main"
    ],
    "schedule": [
      "on the 2nd day of the month"
    ],
    "timezone": "America/Sao_Paulo",
    "labels": [
      "dependencies"
    ],
    "packageRulePrefixes": [
      "[RENOVATE] [PY]",
      "[RENOVATE] [PY] [MAJOR]",
      "[RENOVATE] [CI]"
    ]
  },
  "renovate_workflow": {
    "triggers": {
      "schedule": [
        {
          "cron": "0 5 2 * *"
        }
      ],
      "workflow_dispatch": ""
    },
    "jobs": [
      "renovate"
    ],
    "action": "renovatebot/github-action@v41",
    "configurationFile": ".github/renovate.json5"
  },
  "dupehound_workflow": {
    "triggers": {
      "pull_request": {
        "paths": [
          "src/**",
          "tests/**"
        ]
      },
      "push": {
        "branches": [
          "main"
        ],
        "paths": [
          "src/**",
          "tests/**"
        ]
      }
    },
    "jobs": [
      "check",
      "scan"
    ],
    "check_continue_on_error": "true",
    "scan_summary_lines": [
      "dupehound scan . | tee /tmp/dh-scan.txt",
      "echo \"## dupehound slop score\" >> \"$GITHUB_STEP_SUMMARY\""
    ]
  }
}
Evidence: focused daemon/admin regression test transcript
................................................                         [100%]
48 passed in 0.09s

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

✅ No issues found.

🔧 **Rebase** - 2 issues found → auto-fixed ✅
  • ⚠️ src/browser_harness/admin.py - merge conflict rebasing onto origin/main
  • ⚠️ src/browser_harness/daemon.py - merge conflict rebasing onto origin/main

🔧 Fix applied.
✅ Re-checked - no issues remain.

⏭️ **Review** - skipped
  • ⚠️ .github/workflows/dupehound.yml:22 - continue-on-error: true makes the "Block new duplicates" job non-blocking, so PRs with new duplication still pass the workflow. If the intent is to gate regressions, this setting defeats the check entirely.
  • ⚠️ .github/workflows/dupehound.yml:30 - The workflow downloads and executes dupehound from releases/latest with no version pin or checksum verification. That makes CI non-reproducible and creates a supply-chain exposure: any upstream release change immediately alters what runs on every PR.
  • ⚠️ .github/workflows/renovate.yml:12 - This workflow reintroduces mutable GitHub Action tags (actions/checkout@v4, renovatebot/github-action@v41) after the repo already added SHA pinning. Those tags can move without a PR in this repo, weakening the supply-chain hardening that earlier CI changes established.
✅ **Test** - passed

✅ No issues found.

  • uv run --python 3.12 --with pytest pytest -q tests/unit
  • uv run --python 3.12 --with pytest pytest -q tests/unit/test_daemon.py tests/unit/test_admin.py
  • mkdir -p /var/folders/h_/qkglyg0x5rg5vd2s3y84dh9w0000gn/T/no-mistakes-evidence/01KVZBEFMX9X5MEDS2PQHQ9N3Q && ./browser-harness --doctor | tee /var/folders/h_/qkglyg0x5rg5vd2s3y84dh9w0000gn/T/no-mistakes-evidence/01KVZBEFMX9X5MEDS2PQHQ9N3Q/browser-harness-doctor.txt
  • uv run --python 3.12 --with pyyaml --with json5 python - <<'PY' > /var/folders/h_/qkglyg0x5rg5vd2s3y84dh9w0000gn/T/no-mistakes-evidence/01KVZBEFMX9X5MEDS2PQHQ9N3Q/workflow-config-summary.txt ... PY
  • git diff 7594909e7963c9ba328e39cc79e9f20ff94b2a82..8d5b3b56bc94735c90ef52820c11da8b8d40d4e4 -- .github/workflows/dupehound.yml .github/workflows/renovate.yml .github/renovate.json5 .no-mistakes.yaml agent-workspace/SMOKE.md src/browser_harness/admin.py src/browser_harness/daemon.py
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.


Summary by cubic

Deduplicated env loading in the browser harness by reusing the shared _load_env, fixing the admin shadowing bug and ensuring consistent env init. Added repo automation with monthly Renovate and dupehound CI to surface duplication and a slop score.

  • Refactors

    • src/browser_harness/admin.py and src/browser_harness/daemon.py now import _load_env from helpers; removed duplicate loaders.
    • Env now loads once at import, resolving the admin loader shadowing issue.
  • New Features

    • Added Renovate config and workflow for monthly dependency PRs against main (14-day minimum age; majors require manual review).
    • Added dupehound workflow on PRs and main pushes touching src/** or tests/**; reports new duplication and posts a slop score (non-blocking for now).

Written for commit 05e7e00. Summary will update on new commits.

Review in cubic

giatti added 10 commits June 25, 2026 09:18
- Monthly Renovate run (2nd of month, 02:00 BRT)
- minimumReleaseAge: 14 days (supply-chain protection)
- Python deps via pep621 manager
- Major bumps require manual review
admin.py and daemon.py each defined _load_env and _load_env_file
identically (admin.py: 12-30, daemon.py: 10-28). Both now import
from helpers.py, which is the canonical source (was already exporting
both via module-level _load_env() side effect).

CI:
- .github/workflows/dupehound.yml: scan (slop score) and check
  (--diff against base) jobs. check is continue-on-error for now;
  promote to gate after FP rate <10% over ~10 PRs.

Slop score: 0.9% -> 0.0% (4 -> 0 clusters, 18 lines eliminated).
40/40 unit tests pass.

@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: 05e7e005ff

ℹ️ 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".

from . import _ipc as ipc
from . import auth
from . import paths
from .helpers import _load_env

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop importing helpers for env loading

This import executes the whole helpers module, and helpers.py:508 unconditionally runs _load_agent_helpers(). In any install where agent-workspace/agent_helpers.py contains task-specific top-level code or an import that is only valid during helper scripts, simply importing browser_harness.admin for commands like --doctor, --reload, or daemon management now raises before the admin command can run; previously env loading in admin/daemon did not load agent helpers. Keep env parsing in a side-effect-free module or avoid importing helpers here.

Useful? React with 👍 / 👎.

name: Block new duplicates
runs-on: ubuntu-latest
timeout-minutes: 5
continue-on-error: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove the non-blocking dupehound gate

check is the only job running dupehound check, but job-level continue-on-error: true makes its failure non-fatal for the workflow. In PRs touching src/** or tests/** that introduce duplicates, this contradicts the documented blocking behavior in README/AGENTS and lets the workflow pass as long as the separate scan job succeeds; remove this flag or keep it only on non-gating reporting jobs.

Useful? React with 👍 / 👎.

uses: renovatebot/github-action@v41
with:
configurationFile: .github/renovate.json5
token: ${{ secrets.GITHUB_TOKEN }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use a real Renovate token

For the scheduled Renovate workflow, ${{ secrets.GITHUB_TOKEN }} makes dependency PRs come from the workflow token; Renovate's GitHub Action docs note that this token is too restrictive and PRs made with it do not trigger PR/push CI events (https://github.com/renovatebot/github-action#token). That means the monthly update PRs, including workflow updates covered by the github-actions rule, can arrive without the checks this repo relies on; use a PAT or GitHub App token secret with the required workflow permissions instead.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-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.

8 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/dupehound.yml">

<violation number="1" location=".github/workflows/dupehound.yml:22">
P2: Job named "Block new duplicates" sets `continue-on-error: true`, which means the job never blocks CI — the name contradicts the actual enforcement behavior.</violation>

<violation number="2" location=".github/workflows/dupehound.yml:30">
P1: Unpinned binary download from `releases/latest` without checksum verification introduces supply-chain risk — a new release could silently change behavior or introduce malicious code.</violation>

<violation number="3" location=".github/workflows/dupehound.yml:39">
P2: `HEAD~1` only goes back one commit, which may miss duplicates introduced in earlier commits of a multi-commit push to `main`.</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:74">
P2: Describes dupehound as "blocking new duplication" but the workflow uses `continue-on-error: true` on the "Block new duplicates" job, making it non-blocking — the docs overstate enforcement.</violation>
</file>

<file name=".github/workflows/renovate.yml">

<violation number="1" location=".github/workflows/renovate.yml:12">
P3: No explicit `permissions:` block. Add one to restrict the default token scope by default. Even though the GITHUB_TOKEN issue above makes a PAT the right fix, adding a `permissions:` block aligns with the repo's existing convention (dupehound.yml, release.yml both declare explicit permissions).</violation>

<violation number="2" location=".github/workflows/renovate.yml:12">
P2: Mutable action tags (`@v4`, `@v41`) are used instead of pinned SHAs. While `pinDigests: true` in renovate.json5 will auto-pin these on first run, the initial state is unpinned. Pin them pre-emptively to match the supply-chain hardening pattern already established by `dupehound.yml`.</violation>

<violation number="3" location=".github/workflows/renovate.yml:18">
P1: Using `secrets.GITHUB_TOKEN` with the Renovate action prevents CI workflows from running on Renovate-created PRs, and the token lacks the `workflow` scope required by the `github-actions` manager. The Renovate docs explicitly warn against this — it will silently drop all CI gating on dependency updates.</violation>
</file>

<file name="src/browser_harness/admin.py">

<violation number="1" location="src/browser_harness/admin.py:14">
P1: Importing `_load_env` from `.helpers` triggers execution of the entire `helpers` module at import time. If `helpers.py` has top-level side effects (e.g., calling `_load_agent_helpers()` unconditionally), then simply importing `browser_harness.admin` for lightweight commands like `--doctor` or `--reload` may raise before the admin command runs. The previous implementation kept env parsing local and side-effect-free. Consider either guarding the side-effectful code in `helpers.py` behind `if __name__` / a lazy call, or moving `_load_env` into a minimal, side-effect-free utility module.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

fetch-depth: 0
- name: Install dupehound
run: |
curl -sL https://github.com/Rafaelpta/dupehound/releases/latest/download/dupehound-x86_64-unknown-linux-gnu.tar.gz | tar xz

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P1: Unpinned binary download from releases/latest without checksum verification introduces supply-chain risk — a new release could silently change behavior or introduce malicious code.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/dupehound.yml, line 30:

<comment>Unpinned binary download from `releases/latest` without checksum verification introduces supply-chain risk — a new release could silently change behavior or introduce malicious code.</comment>

<file context>
@@ -0,0 +1,58 @@
+          fetch-depth: 0
+      - name: Install dupehound
+        run: |
+          curl -sL https://github.com/Rafaelpta/dupehound/releases/latest/download/dupehound-x86_64-unknown-linux-gnu.tar.gz | tar xz
+          sudo mv dupehound /usr/local/bin/
+      - name: Block new duplicates vs base
</file context>
Fix with cubic

uses: renovatebot/github-action@v41
with:
configurationFile: .github/renovate.json5
token: ${{ secrets.GITHUB_TOKEN }}

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P1: Using secrets.GITHUB_TOKEN with the Renovate action prevents CI workflows from running on Renovate-created PRs, and the token lacks the workflow scope required by the github-actions manager. The Renovate docs explicitly warn against this — it will silently drop all CI gating on dependency updates.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/renovate.yml, line 18:

<comment>Using `secrets.GITHUB_TOKEN` with the Renovate action prevents CI workflows from running on Renovate-created PRs, and the token lacks the `workflow` scope required by the `github-actions` manager. The Renovate docs explicitly warn against this — it will silently drop all CI gating on dependency updates.</comment>

<file context>
@@ -0,0 +1,20 @@
+        uses: renovatebot/github-action@v41
+        with:
+          configurationFile: .github/renovate.json5
+          token: ${{ secrets.GITHUB_TOKEN }}
+        env:
+          LOG_LEVEL: info
</file context>
Fix with cubic

from . import _ipc as ipc
from . import auth
from . import paths
from .helpers import _load_env

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P1: Importing _load_env from .helpers triggers execution of the entire helpers module at import time. If helpers.py has top-level side effects (e.g., calling _load_agent_helpers() unconditionally), then simply importing browser_harness.admin for lightweight commands like --doctor or --reload may raise before the admin command runs. The previous implementation kept env parsing local and side-effect-free. Consider either guarding the side-effectful code in helpers.py behind if __name__ / a lazy call, or moving _load_env into a minimal, side-effect-free utility module.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/browser_harness/admin.py, line 14:

<comment>Importing `_load_env` from `.helpers` triggers execution of the entire `helpers` module at import time. If `helpers.py` has top-level side effects (e.g., calling `_load_agent_helpers()` unconditionally), then simply importing `browser_harness.admin` for lightweight commands like `--doctor` or `--reload` may raise before the admin command runs. The previous implementation kept env parsing local and side-effect-free. Consider either guarding the side-effectful code in `helpers.py` behind `if __name__` / a lazy call, or moving `_load_env` into a minimal, side-effect-free utility module.</comment>

<file context>
@@ -11,6 +11,7 @@
 from . import _ipc as ipc
 from . import auth
 from . import paths
+from .helpers import _load_env
 
 
</file context>
Fix with cubic

if [ -n "$PR_BASE" ]; then
dupehound check --diff "origin/$PR_BASE" .
else
dupehound check --diff HEAD~1 .

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P2: HEAD~1 only goes back one commit, which may miss duplicates introduced in earlier commits of a multi-commit push to main.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/dupehound.yml, line 39:

<comment>`HEAD~1` only goes back one commit, which may miss duplicates introduced in earlier commits of a multi-commit push to `main`.</comment>

<file context>
@@ -0,0 +1,58 @@
+          if [ -n "$PR_BASE" ]; then
+            dupehound check --diff "origin/$PR_BASE" .
+          else
+            dupehound check --diff HEAD~1 .
+          fi
+
</file context>
Fix with cubic

name: Block new duplicates
runs-on: ubuntu-latest
timeout-minutes: 5
continue-on-error: true

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P2: Job named "Block new duplicates" sets continue-on-error: true, which means the job never blocks CI — the name contradicts the actual enforcement behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/dupehound.yml, line 22:

<comment>Job named "Block new duplicates" sets `continue-on-error: true`, which means the job never blocks CI — the name contradicts the actual enforcement behavior.</comment>

<file context>
@@ -0,0 +1,58 @@
+    name: Block new duplicates
+    runs-on: ubuntu-latest
+    timeout-minutes: 5
+    continue-on-error: true
+    steps:
+      - name: Checkout
</file context>
Suggested change
continue-on-error: true
continue-on-error: false
Fix with cubic

Comment thread README.md
GitHub automation also runs alongside local development:

- Renovate opens monthly dependency update PRs against `main` using `.github/renovate.json5`.
- `dupehound` runs on PRs and `main` pushes that touch `src/**` or `tests/**`, blocking new duplication and publishing a repo slop score in the workflow summary.

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P2: Describes dupehound as "blocking new duplication" but the workflow uses continue-on-error: true on the "Block new duplicates" job, making it non-blocking — the docs overstate enforcement.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At README.md, line 74:

<comment>Describes dupehound as "blocking new duplication" but the workflow uses `continue-on-error: true` on the "Block new duplicates" job, making it non-blocking — the docs overstate enforcement.</comment>

<file context>
@@ -68,6 +68,11 @@ PY
+GitHub automation also runs alongside local development:
+
+- Renovate opens monthly dependency update PRs against `main` using `.github/renovate.json5`.
+- `dupehound` runs on PRs and `main` pushes that touch `src/**` or `tests/**`, blocking new duplication and publishing a repo slop score in the workflow summary.
+
 ## Contributing
</file context>
Suggested change
- `dupehound` runs on PRs and `main` pushes that touch `src/**` or `tests/**`, blocking new duplication and publishing a repo slop score in the workflow summary.
- `dupehound` runs on PRs and `main` pushes that touch `src/**` or `tests/**`, flagging new duplication and publishing a repo slop score in the workflow summary.
Fix with cubic

runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P2: Mutable action tags (@v4, @v41) are used instead of pinned SHAs. While pinDigests: true in renovate.json5 will auto-pin these on first run, the initial state is unpinned. Pin them pre-emptively to match the supply-chain hardening pattern already established by dupehound.yml.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/renovate.yml, line 12:

<comment>Mutable action tags (`@v4`, `@v41`) are used instead of pinned SHAs. While `pinDigests: true` in renovate.json5 will auto-pin these on first run, the initial state is unpinned. Pin them pre-emptively to match the supply-chain hardening pattern already established by `dupehound.yml`.</comment>

<file context>
@@ -0,0 +1,20 @@
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Self-hosted Renovate
</file context>
Fix with cubic

@@ -0,0 +1,20 @@
name: Renovate

@cubic-dev-ai cubic-dev-ai Bot Jun 25, 2026

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.

P3: No explicit permissions: block. Add one to restrict the default token scope by default. Even though the GITHUB_TOKEN issue above makes a PAT the right fix, adding a permissions: block aligns with the repo's existing convention (dupehound.yml, release.yml both declare explicit permissions).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/renovate.yml, line 12:

<comment>No explicit `permissions:` block. Add one to restrict the default token scope by default. Even though the GITHUB_TOKEN issue above makes a PAT the right fix, adding a `permissions:` block aligns with the repo's existing convention (dupehound.yml, release.yml both declare explicit permissions).</comment>

<file context>
@@ -0,0 +1,20 @@
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Self-hosted Renovate
</file context>
Fix with cubic

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.

1 participant