Skip to content

ci: push :stable tag on main push (alongside :latest) - #1

Closed
bsgdigital wants to merge 1 commit into
mainfrom
fix/ci-stable-tag
Closed

bsgdigital wants to merge 1 commit into
mainfrom
fix/ci-stable-tag

Conversation

@bsgdigital

Copy link
Copy Markdown
Contributor

What

The install.sh pulls ghcr.io/fox-in-the-box-ai/cloud:stable but CI only pushed :latest.
This adds a step to tag and push :stable on every push to main.

Change

  • After existing push-to-ghcr step, tag :latest → :stable and push it
  • Only runs on push events (not PRs)

No rebuild cost — just a docker tag + docker push.

@bsgdigital bsgdigital closed this May 1, 2026
@bsgdigital
bsgdigital deleted the fix/ci-stable-tag branch May 1, 2026 00:07
roadhero added a commit that referenced this pull request May 6, 2026
…#123)

Pulls in:
- hermes-webui#6 — exempt /api/ollama/ and /api/local-fallback/ from the
  onboarding redirect middleware. Wizard's setup.js boot probes for
  Ollama detection and bundled local-fallback CTA were silently failing
  because the redirect to /setup confused fetch's JSON parser. With this
  the wizard's local-model fast-paths render correctly when Ollama is
  running on the host.
- hermes-webui#7 — close the race where useLocalOllama scheduled a 800ms
  delayed redirect to / but left the wizard interactive in the meantime,
  letting users click Next mid-redirect and land in chat from a stale
  Step 2 input click.
- hermes-webui#8 — restructure the wizard so picking a local model on
  Step 1 advances to Step 2 (now optional with "Continue with local
  only" CTA) and Step 3 (summary), rather than completing onboarding
  immediately. Onboarding now completes only at Step 3's Open Fox button,
  regardless of which path the user took.

End-to-end verified against a real-host Ollama install: wizard detects
gemma4:latest, "Use" advances through Step 2 → Step 3 → Open Fox, chat
loads with gemma4 active and responds to messages. (#122 #1, partial #3,
#4.)

Remaining #122 failures (#2 Tailscale HTTPS, partial #3 Settings toggle,
#5 Ollama models in chat dropdown, #6 reactive failover, #7 recovery
banner) need separate investigation against a clean :stable build.
roadhero added a commit that referenced this pull request May 16, 2026
Plan §Phase 1 risk #1: "verify pnpm-workspace.yaml only enumerates JS
packages." packages/* glob tolerates Python-only sibling directories
today (pnpm ignores dirs without package.json) but explicit enumeration
is the recommended mitigation, and prevents future contributors who add
a package.json under a Python package directory from accidentally
joining the JS workspace.

packages/integration/ and packages/scripts/ never had package.json so
this change does not affect today's pnpm graph; verified with
`pnpm install --frozen-lockfile` (clean).

Refs #165.
roadhero added a commit that referenced this pull request May 16, 2026
…n (Phase 1) (#219)

* feat(fox-overlay): scaffold packages/fox-overlay/ for v0.6.0 migration

Sibling overlay package that will hold all Fox-in-the-Box-specific code
so the forks/hermes-{agent,webui} submodules can pin virgin upstream tags
(Phase 8). This commit ships only the scaffold; subsequent phases (2-10)
populate it.

Tree shape:
  packages/fox-overlay/
  ├── pyproject.toml          entry-point commented until Phase 3
  ├── MANIFEST.toml           empty inventory placeholder
  ├── README.md
  ├── .fox-removals           empty manifest (Phase 2/7 fill)
  ├── .gitignore              *.egg-info/
  ├── fox_overlay/
  │   ├── bootstrap.py        FOX_OVERLAY_AUTOINSTALL-gated install()
  │   ├── webui_modules/      Phase 5 target
  │   ├── webui_patches/      Phase 6 target
  │   └── agent_plugins/      Phase 3 target
  ├── webui_static/.gitkeep   Phase 2 target
  ├── patches/{webui,agent}/series  Phase 4 target
  └── scripts/check-overlay-basis.sh  no-op stub; Phase 8 makes it real

Anti-regression Rule 4 honored: bootstrap.install() is gated by
FOX_OVERLAY_AUTOINSTALL (default on; set =0 to opt out for tests, REPL,
hot-reloaders, IDE indexers). Without the gate, any Phase 4-6 monkey-patch
that install() registers would fire from any unintended import path.

No behavior change in this commit: Dockerfile is untouched, the overlay
isn't pip install'd in the image yet, no entry-points wired, no patches
populated.

Validated locally:
- pip install -e packages/fox-overlay/ from a fresh venv builds an
  editable wheel cleanly
- python -c "import fox_overlay.bootstrap" prints the install log line
- FOX_OVERLAY_AUTOINSTALL=0 leaves _INSTALLED=False until install() is
  called explicitly

Refs #165 (sub-issue of #164 — Phase 1 of v0.6.0 epic #155).

* docs(AGENTS.md): note packages/fox-overlay/ in Repository Layout

Phase 1 introduces packages/fox-overlay/. Updating AGENTS.md (the
repo-tracked agent-facing layout doc — CLAUDE.md is gitignored per
repo policy "keep CLAUDE.md local only") so the on-disk tree and the
doc stay aligned.

Refs #165.

* chore(workspace): narrow pnpm-workspace.yaml to JS packages explicitly

Plan §Phase 1 risk #1: "verify pnpm-workspace.yaml only enumerates JS
packages." packages/* glob tolerates Python-only sibling directories
today (pnpm ignores dirs without package.json) but explicit enumeration
is the recommended mitigation, and prevents future contributors who add
a package.json under a Python package directory from accidentally
joining the JS workspace.

packages/integration/ and packages/scripts/ never had package.json so
this change does not affect today's pnpm graph; verified with
`pnpm install --frozen-lockfile` (clean).

Refs #165.

* test(fox-overlay): add bootstrap idempotency + autoinstall regression tests

Three pytest cases covering the bootstrap.install() contract:
- test_install_is_idempotent — second install() returns cleanly
- test_autoinstall_default_on — without env var, import triggers install
- test_autoinstall_opt_out — FOX_OVERLAY_AUTOINSTALL=0 leaves _INSTALLED
  False until install() is called explicitly

Seeds packages/fox-overlay/tests/ for Phases 3-6 to extend per
anti-regression Rule 3 ("regression test suite grows with every phase").

Refs #165.
roadhero added a commit that referenced this pull request May 17, 2026
Reverts the mem0_oss-relocation portion of this PR per Reviewer #2 and
Reviewer #3's HIGH finding during Phase 3b review. Architectural
mismatch: upstream's memory-provider discovery is a separate
directory-scan path (plugins/memory/__init__.py) with its own
FakePluginContext exposing register_memory_provider — incompatible
with the standard PluginContext that entry-point-discovered plugins
receive. Relocated mem0_oss could not register a MemoryProvider at
gateway runtime via either the upstream PluginManager OR the gateway
bootstrap shim.

## File changes

  - removed packages/fox-overlay/fox_overlay/agent_plugins/mem0_oss/
    (3 files, ~1218 lines)
  - reverted pyproject.toml: drop mem0ai + qdrant-client dependencies
    (mem0_oss is back as a bundled fork plugin; upstream's own
    discovery path installs its plugin.yaml deps if needed)
  - reverted pyproject.toml entry-points: drop mem0_oss entry; keep
    fox_overlay entry for the 3 monkey-patches
  - reverted agent_plugins/__init__.py: register() no longer imports
    or invokes mem0_oss; docstring updated with deferral rationale
  - reverted MANIFEST.toml: drop mem0_oss entry; add deferral comment
  - bumped hermes-agent submodule pin from e301105e to 0a278fc1 (fork
    main after PR #3 merge which restores plugins/memory/mem0_oss/
    byte-identical to pre-PR-#1 baseline)
  - added packages/fox-overlay/tests/test_agent_overlay.py — 9 pytest
    cases verifying each of the 8 monkey-patch sentinels + idempotency
    of register()

## Net Phase 3 scope (after this revert)

The 3 Fox monkey-patches (Bedrock target_model, auxiliary.default
fallback, cron failure diagnostics) ship as planned via the
fox-overlay entry-point + gateway bootstrap shim. mem0_oss continues
as a bundled fork plugin, working as it did in v0.5.4 — zero user-
visible regression.

## Future work (out of scope for v0.6.0)

A dedicated future phase handles proper memory-provider relocation,
requiring either:
  (a) An upstream PR to NousResearch/hermes-agent adding
      register_memory_provider to the standard PluginContext, OR
  (b) A Fox-side fake-context construction in the overlay that mirrors
      plugins/memory/__init__.py's discovery path.

Refs Reviewer #2 + Reviewer #3 findings on PR #221; rollback decision
by Dennis 2026-05-17 (Option A of three presented).
roadhero added a commit that referenced this pull request May 17, 2026
… (Phase 3b) (#221)

* feat(fox-overlay): agent plugin + monkey-patches + relocated mem0_oss

Phase 3b (monorepo side) of the v0.6.0 upstream-separation migration
(epic #155, sub-issue #171). Companion to merged fork PRs
fox-in-the-box-ai/hermes-agent#1 (revert Fox edits + remove mem0_oss
+ pause notify-monorepo) and #2 (bootstrap shim).

## What this does

Populates packages/fox-overlay/fox_overlay/agent_plugins/ with the
relocated Fox customizations so the gateway boots with Fox bug fixes
restored on top of virgin upstream:

  1. Three monkey-patches against upstream hermes-agent functions,
     applied via `inspect.getsource` + textual substitution at
     register-time (anchor-based; raises AssertionError at startup if
     upstream refactors the target — caught by Phase 9 nightly watch).

     - hermes_cli.runtime_provider.resolve_runtime_provider:
         target_model used for Bedrock api_mode routing
     - agent.auxiliary_client._resolve_task_provider_model:
         provider=auto resolves to explicit provider when cfg_model set
     - agent.auxiliary_client._get_auxiliary_task_config:
         auxiliary.default falls back when no task-specific config
     - cron.jobs.create_job + .mark_job_run: rolling failure_history
     - cron.scheduler.run_job: enriched FAILED output (diagnostics +
       traceback + session-log path)
     - cron.scheduler.tick: structured multi-line failure delivery
     - tools.cronjob_tools._format_job: surface last_error +
       failure_history + consecutive_failures when present

  2. mem0_oss memory provider relocated wholesale from
     forks/hermes-agent/plugins/memory/mem0_oss/ (byte-identical
     restored via git show; SHA256 verified). plugin.yaml gains
     `kind: backend` for upstream v0.13.0's plugin manifest validation.

  3. pyproject.toml entry-points wire fox_overlay + mem0_oss into
     upstream's hermes_agent.plugins group (discovery mechanism
     documented in plan §3 Agent 2).

  4. Dockerfile inserts `COPY packages/fox-overlay /app/fox-overlay` +
     `pip install -e /app/fox-overlay` between the upstream pip
     install (line 141) and the Phase 2 static-overlay ENV block
     (line 143). Layer-cache friendly: static-asset edits don't
     invalidate the (slow) upstream install layer.

  5. Submodule pin bumped to e301105ec (fork main after PR#1 + PR#2
     merged).

## Validation gates

  - Container rebuilds clean (FITB_VERSION=v0.6.0-p3-shim-qa, 1.45 GB)
  - Container starts, /health 200, supervisord all RUNNING
  - Gateway startup log (/data/data/hermes/logs/agent.log) shows all
    8 `[fox-overlay] patched ...` lines confirming each substitution
  - All 8 runtime sentinel attributes True after gateway boot
  - Zero AssertionError / Traceback / ERROR in any log

## Engineer-discovered gap (handled by fork PR #2)

Upstream's PluginManager.discover_and_load() is invoked only from
hermes_cli commands and tui_gateway, never from gateway/run.py. The
plan assumed entry-points auto-fire at gateway boot; they don't.
Resolved via the ~23-line bootstrap shim in fork PR #2 (plan
deviation flagged + Dennis-approved). Net agent patch surface goes
from plan's optimistic 0 files to 1 file / ~23 lines — still within
Phase 8's patch-series model.

## _helpers.py textual-substitution pattern

`substitute_function` reads upstream source via inspect.getsource,
applies (old, new) substitutions sequentially with EXACTLY-ONCE
anchor check, recompiles in a copy of the upstream module's globals,
and rebinds the attribute. Anchor drift → AssertionError at register
time. Idempotent via per-target sentinel.

Notably does NOT call textwrap.dedent — dedent normalizes
whitespace-only blank lines to bare \\n, breaking anchors that match
verbatim file content. Engineer-discovered during integration smoke
(cron.jobs.mark_job_run anchor with 16-space blank line failed
until dedent removed); fix documented in _helpers.py docstring.

## Out of scope (deferred per architect brief)

  - Bootstrap.py changes — Phase 4 owns those (webui-side shim)
  - Webui-side patches — Phase 4-7
  - Submodule re-point to virgin upstream — Phase 8 (extracts the
    fork-PR-#2 shim to packages/fox-overlay/patches/agent/001-*.patch
    at that time)

Closes #171.

* chore(fox-overlay): revert mem0_oss relocation (Phase 3 rollback)

Reverts the mem0_oss-relocation portion of this PR per Reviewer #2 and
Reviewer #3's HIGH finding during Phase 3b review. Architectural
mismatch: upstream's memory-provider discovery is a separate
directory-scan path (plugins/memory/__init__.py) with its own
FakePluginContext exposing register_memory_provider — incompatible
with the standard PluginContext that entry-point-discovered plugins
receive. Relocated mem0_oss could not register a MemoryProvider at
gateway runtime via either the upstream PluginManager OR the gateway
bootstrap shim.

## File changes

  - removed packages/fox-overlay/fox_overlay/agent_plugins/mem0_oss/
    (3 files, ~1218 lines)
  - reverted pyproject.toml: drop mem0ai + qdrant-client dependencies
    (mem0_oss is back as a bundled fork plugin; upstream's own
    discovery path installs its plugin.yaml deps if needed)
  - reverted pyproject.toml entry-points: drop mem0_oss entry; keep
    fox_overlay entry for the 3 monkey-patches
  - reverted agent_plugins/__init__.py: register() no longer imports
    or invokes mem0_oss; docstring updated with deferral rationale
  - reverted MANIFEST.toml: drop mem0_oss entry; add deferral comment
  - bumped hermes-agent submodule pin from e301105e to 0a278fc1 (fork
    main after PR #3 merge which restores plugins/memory/mem0_oss/
    byte-identical to pre-PR-#1 baseline)
  - added packages/fox-overlay/tests/test_agent_overlay.py — 9 pytest
    cases verifying each of the 8 monkey-patch sentinels + idempotency
    of register()

## Net Phase 3 scope (after this revert)

The 3 Fox monkey-patches (Bedrock target_model, auxiliary.default
fallback, cron failure diagnostics) ship as planned via the
fox-overlay entry-point + gateway bootstrap shim. mem0_oss continues
as a bundled fork plugin, working as it did in v0.5.4 — zero user-
visible regression.

## Future work (out of scope for v0.6.0)

A dedicated future phase handles proper memory-provider relocation,
requiring either:
  (a) An upstream PR to NousResearch/hermes-agent adding
      register_memory_provider to the standard PluginContext, OR
  (b) A Fox-side fake-context construction in the overlay that mirrors
      plugins/memory/__init__.py's discovery path.

Refs Reviewer #2 + Reviewer #3 findings on PR #221; rollback decision
by Dennis 2026-05-17 (Option A of three presented).
roadhero added a commit that referenced this pull request May 28, 2026
The streaming patch's local-fallback plumbing anchor expected a dict
closing brace `}` before "Build kwargs defensively", but upstream
v0.51.145 refactored fallback resolution to end with
`_fallback_resolved = _fallback_chain or None` instead. The stale
anchor caused 3 test failures + 3 errors in CI's validate-overlay
(which runs with hermes-webui on PYTHONPATH). Local tests were
unaffected because `api` is not importable without PYTHONPATH, so
bootstrap caught ImportError before reaching the AssertionError.
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