Skip to content

chore(config): declare every ENABLE_<CLI> toggle in each app.yaml overlay - #107

Merged
dgokeeffe merged 34 commits into
mainfrom
chore/overlay-toggle-parity
Aug 5, 2026
Merged

chore(config): declare every ENABLE_<CLI> toggle in each app.yaml overlay#107
dgokeeffe merged 34 commits into
mainfrom
chore/overlay-toggle-parity

Conversation

@dgokeeffe

Copy link
Copy Markdown
Collaborator

Apps overlays replace app.yaml rather than merging, and each ENABLE_* defaults to true when absent — so a toggle omitted from an overlay silently re-enables that CLI's install. app.yaml.template and app.yaml.lakemeter listed only 2 of 5. Adds a test holding the invariant. Salvaged from #30.

dgokeeffe and others added 30 commits May 6, 2026 17:48
Hermes was returning 403 ("Invalid access token") on the first call after
a PAT rotation, then succeeding on retry. Two reasons:

1. update_cli_tokens() rewrote each agent's config file with a bare
   open(path, "w"), creating a window where a concurrent Hermes
   invocation could read a half-written api_key line. Hermes is exposed
   to this because it re-reads ~/.hermes/config.yaml on every call;
   Claude/Codex/Gemini cache the token in env at process startup.
2. Every write path silently swallowed OSError, so an actual write
   failure (perms, locked file, ENOSPC) would leave the config stale
   forever with no log line — the user just saw 403s.

Adds _atomic_write_text() helper (write to .tmp, os.replace) used by
all five _update_* functions. Replaces silent except OSError: pass with
logger.warning at WARNING level. FileNotFoundError still silenced via an
explicit os.path.exists() guard so the rotator doesn't spam during the
brief window between app start and setup script completion.

Co-authored-by: Isaac
Adds supply-chain provenance to every GitHub Release so enterprise
security teams (PCI-DSS / ISO 27001 / APRA CPS 234) can verify what
shipped and prove it came from this repo's workflow.

What's attached to each release now:
- coda-sbom.cdx.json — CycloneDX SBOM (Python + npm deps via syft)
- coda-sbom.cdx.json.cosign.bundle — cosign keyless signature bundle
  (cert + signature + Rekor inclusion proof)

Signing uses GitHub OIDC — no long-lived keys. The signing identity is
anchored to this workflow path and the release tag, and a public
transparency-log entry is recorded in Rekor.

Workflow changes:
- Added `id-token: write` permission (required for OIDC keyless signing)
- Added anchore/sbom-action step (SHA-pinned, format=cyclonedx-json)
- Added sigstore/cosign-installer + sign-blob + in-workflow verify
- Extended softprops/action-gh-release `files:` to attach both artefacts

README changes:
- New "Verifying release provenance" subsection with the cosign
  verify-blob command operators can run.

Co-authored-by: Isaac
databrickslabs/dqx and other Labs projects ship a prominent "Project
Support" block disclaiming SLAs and pointing users at the LICENSE for
binding terms. CoDA has the LICENSE.md (with $1,000 aggregate liability
cap + comprehensive warranty disclaimers) and NOTICE.md (full
third-party attribution), but the README didn't surface either.

Without this block, a user evaluating CoDA could plausibly assume it's
a supported Databricks product because it lives under the
databrickslabs/ org. The disclaimer closes that gap — and is placed
immediately after the tagline (not buried at the bottom) because the
tool exposes a workspace-credential-scoped shell and AI agents that
act with full user authority.

Text lifted from databrickslabs/dqx with one grammar tweak (singular
"It is provided AS-IS" since this is one project, not multiple).
Cross-references LICENSE.md and NOTICE.md so security-conscious readers
can find the binding legal text in one hop.

Co-authored-by: Isaac
Keeps the README lean — release-provenance details now live in
docs/SECURITY.md where security reviewers expect them. Also removes
docs/plans/, which held historical design/implementation notes for
features that have already shipped.

Co-authored-by: Isaac
Updates the requirements on [pytest-playwright](https://github.com/microsoft/playwright-pytest) to permit the latest version.
- [Release notes](https://github.com/microsoft/playwright-pytest/releases)
- [Commits](microsoft/playwright-pytest@v0.5.0...v0.8.0)

---
updated-dependencies:
- dependency-name: pytest-playwright
  dependency-version: 0.8.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [click](https://github.com/pallets/click) from 8.3.3 to 8.4.1.
- [Release notes](https://github.com/pallets/click/releases)
- [Changelog](https://github.com/pallets/click/blob/main/CHANGES.md)
- [Commits](pallets/click@8.3.3...8.4.1)

---
updated-dependencies:
- dependency-name: click
  dependency-version: 8.4.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [idna](https://github.com/kjd/idna) from 3.16 to 3.17.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md)
- [Commits](kjd/idna@v3.16...v3.17)

---
updated-dependencies:
- dependency-name: idna
  dependency-version: '3.17'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [pydantic-core](https://github.com/pydantic/pydantic) from 2.46.4 to 2.47.0.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/commits)

---
updated-dependencies:
- dependency-name: pydantic-core
  dependency-version: 2.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Add a README section explaining the Omnigent host integration merged in #92:
what it does, how to turn it on (with the app.yaml.lakemeter overlay), the
two-credential model (SP-OAuth host tunnel + AI-Gateway harness LLM), the
runtime control endpoints, and the ENABLE_SP_APIKEYHELPER pairing. Also add
the OMNIGENTS_* / ENABLE_SP_APIKEYHELPER rows to the env-var reference table.

The feature shipped in #92 with no user-facing docs (README had zero Omnigent
mentions); this closes that gap.
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 7.0.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@a309ff8...5fda3b9)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](softprops/action-gh-release@b430933...3d0d988)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@9c091bb...3d3c42e)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.1.0 to 9.0.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](astral-sh/setup-uv@0880764...c771a70)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
`pytest_collection_modifyitems` in tests/e2e/conftest.py receives the
whole session's item list, not just this directory's. When the e2e
prerequisites were missing (no recorded auth.json, or the databricks CLI
not authed for the profile) it marked *every* collected test as skipped
— so `uv run pytest tests/` reported "465 skipped" and the CI Tests
workflow was passing vacuously.

Filter to items that actually live under tests/e2e/. The unit suite now
runs: 459 passed, 1 skipped.
…up_proxy

The plan-doc cleanup removed 2026-03-11-litellm-empty-content-blocks-design.md,
but app.py, setup_opencode.py and setup_proxy.py all point readers at it from
code comments. Restore it so those pointers don't dangle.
# Conflicts:
#	docs/auth-and-identity.md
Conflict in _update_claude: keep main's `changed` flag + OTEL-token refresh,
route the write through _atomic_write_text, and surface failures as warnings.

Two gaps fixed while integrating against current main:

- os.replace() installs the tmp file's inode, so the atomic rewrite also
  installed the tmp file's umask-default permissions — widening
  ~/.hermes/config.yaml from the 0600 setup_hermes.py sets back to 0644 on
  every rotation. Copy the target's mode onto the tmp file first.
- _update_pi() landed on main after this PR was opened and still used a bare
  open(path, 'w') with a silent except. Give it the same existence guard,
  atomic write, and observable warning as its siblings.

New tests cover both, plus a 'quiet when nothing is installed' guard so the
new warnings can't become boot noise.
…rlay

Apps overlays *replace* app.yaml rather than merging with it, and every
setup script reads its toggle as `os.environ.get("ENABLE_<CLI>", "true")`.
So a toggle omitted from an overlay is not a no-op — it silently re-enables
that CLI's install on the deployed container.

app.yaml and app.yaml.workshop listed all five; app.yaml.template and
app.yaml.lakemeter listed only ENABLE_HERMES and ENABLE_PI, so deploys from
those overlays would install Codex and Gemini even though neither has a
compatible gateway endpoint — wasted boot time plus agents that fail on
first request.

Adds tests/test_app_yaml_overlays.py to hold the invariant: every tracked
app.yaml* declares all five toggles, values stay quoted strings (unquoted
`true` parses as a bool, which the scripts' .strip().lower() would choke on),
and a new ENABLE_* appearing in setup_*.py fails the test until it's added
to the overlays.

This is the part of #30 that main hadn't already absorbed: the toggle
mechanism itself landed separately, and main's default-on policy for
Hermes/OpenCode is a deliberate later workshop decision.
@dgokeeffe
dgokeeffe merged commit 610d823 into main Aug 5, 2026
@dgokeeffe
dgokeeffe deleted the chore/overlay-toggle-parity branch August 5, 2026 08:04
dgokeeffe pushed a commit that referenced this pull request Aug 5, 2026
…107)

* fix: inject fresh token in proxy to survive PAT rotation

Cherry-picked from PR #105 (dgokeeffe) for testing.

* fix: strip DATABRICKS_HOST from shell env to unblock CLI auth

The Databricks SDK skips ~/.databrickscfg when DATABRICKS_HOST is set
in env (even without credentials). After DATABRICKS_TOKEN and SP
credentials are stripped, the CLI sees host + workspace_id but no
token and fails. Stripping DATABRICKS_HOST forces the SDK to fall
through to ~/.databrickscfg which has both host and token (kept
fresh by PAT rotator). Mirrors the pattern in sync_to_workspace.py.

Ref #105
dgokeeffe added a commit that referenced this pull request Aug 5, 2026
…rlay (#107)

* fix(cli-auth): atomic writes + observable failures on PAT rotation

Hermes was returning 403 ("Invalid access token") on the first call after
a PAT rotation, then succeeding on retry. Two reasons:

1. update_cli_tokens() rewrote each agent's config file with a bare
   open(path, "w"), creating a window where a concurrent Hermes
   invocation could read a half-written api_key line. Hermes is exposed
   to this because it re-reads ~/.hermes/config.yaml on every call;
   Claude/Codex/Gemini cache the token in env at process startup.
2. Every write path silently swallowed OSError, so an actual write
   failure (perms, locked file, ENOSPC) would leave the config stale
   forever with no log line — the user just saw 403s.

Adds _atomic_write_text() helper (write to .tmp, os.replace) used by
all five _update_* functions. Replaces silent except OSError: pass with
logger.warning at WARNING level. FileNotFoundError still silenced via an
explicit os.path.exists() guard so the rotator doesn't spam during the
brief window between app start and setup script completion.

Co-authored-by: Isaac

* ci(release): generate signed SBOM on each release

Adds supply-chain provenance to every GitHub Release so enterprise
security teams (PCI-DSS / ISO 27001 / APRA CPS 234) can verify what
shipped and prove it came from this repo's workflow.

What's attached to each release now:
- coda-sbom.cdx.json — CycloneDX SBOM (Python + npm deps via syft)
- coda-sbom.cdx.json.cosign.bundle — cosign keyless signature bundle
  (cert + signature + Rekor inclusion proof)

Signing uses GitHub OIDC — no long-lived keys. The signing identity is
anchored to this workflow path and the release tag, and a public
transparency-log entry is recorded in Rekor.

Workflow changes:
- Added `id-token: write` permission (required for OIDC keyless signing)
- Added anchore/sbom-action step (SHA-pinned, format=cyclonedx-json)
- Added sigstore/cosign-installer + sign-blob + in-workflow verify
- Extended softprops/action-gh-release `files:` to attach both artefacts

README changes:
- New "Verifying release provenance" subsection with the cosign
  verify-blob command operators can run.

Co-authored-by: Isaac

* docs(legal): add Project Support / AS-IS disclaimer to README

databrickslabs/dqx and other Labs projects ship a prominent "Project
Support" block disclaiming SLAs and pointing users at the LICENSE for
binding terms. CoDA has the LICENSE.md (with $1,000 aggregate liability
cap + comprehensive warranty disclaimers) and NOTICE.md (full
third-party attribution), but the README didn't surface either.

Without this block, a user evaluating CoDA could plausibly assume it's
a supported Databricks product because it lives under the
databrickslabs/ org. The disclaimer closes that gap — and is placed
immediately after the tagline (not buried at the bottom) because the
tool exposes a workspace-credential-scoped shell and AI agents that
act with full user authority.

Text lifted from databrickslabs/dqx with one grammar tweak (singular
"It is provided AS-IS" since this is one project, not multiple).
Cross-references LICENSE.md and NOTICE.md so security-conscious readers
can find the binding legal text in one hop.

Co-authored-by: Isaac

* docs: move SBOM verification to docs/SECURITY.md, drop stale plans

Keeps the README lean — release-provenance details now live in
docs/SECURITY.md where security reviewers expect them. Also removes
docs/plans/, which held historical design/implementation notes for
features that have already shipped.

Co-authored-by: Isaac

* chore(deps-dev): update pytest-playwright requirement

Updates the requirements on [pytest-playwright](https://github.com/microsoft/playwright-pytest) to permit the latest version.
- [Release notes](https://github.com/microsoft/playwright-pytest/releases)
- [Commits](microsoft/playwright-pytest@v0.5.0...v0.8.0)

---
updated-dependencies:
- dependency-name: pytest-playwright
  dependency-version: 0.8.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump click from 8.3.3 to 8.4.1

Bumps [click](https://github.com/pallets/click) from 8.3.3 to 8.4.1.
- [Release notes](https://github.com/pallets/click/releases)
- [Changelog](https://github.com/pallets/click/blob/main/CHANGES.md)
- [Commits](pallets/click@8.3.3...8.4.1)

---
updated-dependencies:
- dependency-name: click
  dependency-version: 8.4.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump idna from 3.16 to 3.17

Bumps [idna](https://github.com/kjd/idna) from 3.16 to 3.17.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md)
- [Commits](kjd/idna@v3.16...v3.17)

---
updated-dependencies:
- dependency-name: idna
  dependency-version: '3.17'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump pydantic-core from 2.46.4 to 2.47.0

Bumps [pydantic-core](https://github.com/pydantic/pydantic) from 2.46.4 to 2.47.0.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/commits)

---
updated-dependencies:
- dependency-name: pydantic-core
  dependency-version: 2.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* docs: document Omnigent host integration

Add a README section explaining the Omnigent host integration merged in #92:
what it does, how to turn it on (with the app.yaml.lakemeter overlay), the
two-credential model (SP-OAuth host tunnel + AI-Gateway harness LLM), the
runtime control endpoints, and the ENABLE_SP_APIKEYHELPER pairing. Also add
the OMNIGENTS_* / ENABLE_SP_APIKEYHELPER rows to the env-var reference table.

The feature shipped in #92 with no user-facing docs (README had zero Omnigent
mentions); this closes that gap.

* docs: correct Omnigent identity and grant guidance

* docs(auth): describe loopback SP token broker

* chore(deps): bump actions/setup-python from 6.2.0 to 7.0.0

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 7.0.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@a309ff8...5fda3b9)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump softprops/action-gh-release from 3.0.0 to 3.0.2

Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](softprops/action-gh-release@b430933...3d0d988)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump actions/checkout from 7.0.0 to 7.0.1

Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@9c091bb...3d3c42e)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump astral-sh/setup-uv from 8.1.0 to 9.0.0

Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.1.0 to 9.0.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](astral-sh/setup-uv@0880764...c771a70)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(tests): scope e2e prerequisite skip to the e2e directory

`pytest_collection_modifyitems` in tests/e2e/conftest.py receives the
whole session's item list, not just this directory's. When the e2e
prerequisites were missing (no recorded auth.json, or the databricks CLI
not authed for the profile) it marked *every* collected test as skipped
— so `uv run pytest tests/` reported "465 skipped" and the CI Tests
workflow was passing vacuously.

Filter to items that actually live under tests/e2e/. The unit suite now
runs: 459 passed, 1 skipped.

* docs: keep litellm design doc referenced by app.py/setup_opencode/setup_proxy

The plan-doc cleanup removed 2026-03-11-litellm-empty-content-blocks-design.md,
but app.py, setup_opencode.py and setup_proxy.py all point readers at it from
code comments. Restore it so those pointers don't dangle.

* chore(config): declare every ENABLE_<CLI> toggle in each app.yaml overlay

Apps overlays *replace* app.yaml rather than merging with it, and every
setup script reads its toggle as `os.environ.get("ENABLE_<CLI>", "true")`.
So a toggle omitted from an overlay is not a no-op — it silently re-enables
that CLI's install on the deployed container.

app.yaml and app.yaml.workshop listed all five; app.yaml.template and
app.yaml.lakemeter listed only ENABLE_HERMES and ENABLE_PI, so deploys from
those overlays would install Codex and Gemini even though neither has a
compatible gateway endpoint — wasted boot time plus agents that fail on
first request.

Adds tests/test_app_yaml_overlays.py to hold the invariant: every tracked
app.yaml* declares all five toggles, values stay quoted strings (unquoted
`true` parses as a bool, which the scripts' .strip().lower() would choke on),
and a new ENABLE_* appearing in setup_*.py fails the test until it's added
to the overlays.

This is the part of #30 that main hadn't already absorbed: the toggle
mechanism itself landed separately, and main's default-on policy for
Hermes/OpenCode is a deliberate later workshop decision.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: mpkrass7 <mpkrass@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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