Skip to content

test: isolate the offline suite from owner/private live defaults - #318

Merged
Coding-Dev-Tools merged 987 commits into
mainfrom
test/offline-suite-isolation
Nov 5, 2026
Merged

Coding-Dev-Tools merged 987 commits into
mainfrom
test/offline-suite-isolation

Conversation

@Coding-Dev-Tools

Copy link
Copy Markdown
Owner

Summary

Re-submits the offline-suite isolation fix from closed #313.

An owner-private ~/.engraphis/config.env can enable live extraction, retention supervision, or a BYOK decision backend. The autouse fixture already pins paths, models, and cloud credentials; this also pins the provider features and removes provider key variables so the documented offline gate cannot block on a live DNS lookup. Tests that exercise these paths opt in explicitly with monkeypatch.

Verification

  • The 14 affected config/Jev/LLM/retention modules passed.
  • ruff check . — clean.
  • Test-only change; branch is reconciled with current main.

Agent: commandcode

Coding-Dev-Tools and others added 30 commits August 23, 2026 03:25
Windows wall-clock resolution can tie _mark_authoritative_denial to the
reconnect bootstrap's entitlement_checked_at, so the strict > in
_clear_superseded_denial never fires and the guard sticks. Back-date the
denial stamp so the test asserts supersession logic, not host clock
granularity.
…dow width

A sweep whose now ties a memory's ingest instant (~15.6 ms Windows clock
ticks) cannot separate 'live' from 'historical': closing [t, t) hides the
fact from every as_of read, while clamping valid_to forward (valid_from +
1us, the previous approach) leaves the just-archived row live-visible to
every read sampling the remainder of the same tick — observed as an
intermittent failure of test_consolidate_archives_decayed_transients_but_
not_pinned (~1/8 module runs).

Defer instead: the tied sweep leaves the memory live and reports it via
report['archive_deferred']; a strictly later sweep closes it with ordinary
half-open semantics. Production sweeps run minutes apart, so deferral is
unobservable there. Tests asserting closed-path archives now back-date
valid_from deterministically rather than racing the host clock.
…dow width


A sweep whose now ties a memory's ingest instant (~15.6 ms Windows clock
ticks) cannot separate 'live' from 'historical': closing [t, t) hides the
fact from every as_of read, while clamping valid_to forward (valid_from +
1us, the previous approach) leaves the just-archived row live-visible to
every read sampling the remainder of the same tick — observed as an
intermittent failure of test_consolidate_archives_decayed_transients_but_
not_pinned (~1/8 module runs).

Defer instead: the tied sweep leaves the memory live and reports it via
report['archive_deferred']; a strictly later sweep closes it with ordinary
half-open semantics. Production sweeps run minutes apart, so deferral is
unobservable there. Tests asserting closed-path archives now back-date
valid_from deterministically rather than racing the host clock.
…rphan sessions

FastMCP's default stateful streamable-HTTP mode tracks session ids in
memory, so every engraphis-mcp-http bounce (pm2 resurrect, watchdog,
manual restart) invalidated all live sessions: the client's next request
got a 404, the mcp SDK raised 'Session terminated', and Hermes gateway
clients parked for their full 300s retry interval with zero registered
tools (60+ such restart cycles in hermes-logs/engraphis-mcp-http.log).

Set stateless_http on the standalone launcher's server so every POST is
self-contained per the MCP spec; spec-compliant clients skip the absent
GET SSE stream (405). stdio and dashboard mounts keep their defaults.
…rphan sessions


FastMCP's default stateful streamable-HTTP mode tracks session ids in
memory, so every engraphis-mcp-http bounce (pm2 resurrect, watchdog,
manual restart) invalidated all live sessions: the client's next request
got a 404, the mcp SDK raised 'Session terminated', and Hermes gateway
clients parked for their full 300s retry interval with zero registered
tools (60+ such restart cycles in hermes-logs/engraphis-mcp-http.log).

Set stateless_http on the standalone launcher's server so every POST is
self-contained per the MCP spec; spec-compliant clients skip the absent
GET SSE stream (405). stdio and dashboard mounts keep their defaults.
- dependabot.yml: group github/codeql-action/* so init+analyze always bump
  in one PR; a mixed-version pair deterministically fails CodeQL's analyze
  post-action step (seen on open dependabot #157/#158)
- .gitignore: schema-migration flock (.*.migration.lock, held live while
  the server runs) plus regenerable root-level diagnostic dumps
  (/404_paths.txt /disk_report.txt /large_files.txt /stats_pm2.txt
  /venv_status.txt /r3.txt)
- dependabot.yml: group github/codeql-action/* so init+analyze always bump
  in one PR; a mixed-version pair deterministically fails CodeQL's analyze
  post-action step (seen on open dependabot #157/#158)
- .gitignore: schema-migration flock (.*.migration.lock, held live while
  the server runs) plus regenerable root-level diagnostic dumps
  (/404_paths.txt /disk_report.txt /large_files.txt /stats_pm2.txt
  /venv_status.txt /r3.txt)
… an LLM extractor

MemoryService picks up the owner's ~/.engraphis/config.env, so on machines
with ENGRAPHIS_EXTRACTOR=llm every engine.ingest() call in the suite made a
live extraction request (10-90s through the local proxy). That starved
test_session_close_linearizes_before_delayed_memory_write[ingest]'s 10s
worker budget and made the 'offline gate' network-dependent.

Force ENGRAPHIS_EXTRACTOR=none via os.environ.setdefault, mirroring the
existing ENGRAPHIS_UPDATE_CHECK=0 posture: real shell overrides still win
(config.env itself uses setdefault), and tests exercising extraction opt
in explicitly. Idempotent file: 41s+ with live calls -> 8.9s offline.
… an LLM extractor


MemoryService picks up the owner's ~/.engraphis/config.env, so on machines
with ENGRAPHIS_EXTRACTOR=llm every engine.ingest() call in the suite made a
live extraction request (10-90s through the local proxy). That starved
test_session_close_linearizes_before_delayed_memory_write[ingest]'s 10s
worker budget and made the 'offline gate' network-dependent.

Force ENGRAPHIS_EXTRACTOR=none via os.environ.setdefault, mirroring the
existing ENGRAPHIS_UPDATE_CHECK=0 posture: real shell overrides still win
(config.env itself uses setdefault), and tests exercising extraction opt
in explicitly. Idempotent file: 41s+ with live calls -> 8.9s offline.
- Raise MAX_IMPORT_FILES 500 -> 1,500 and total bytes to 750 MB; document/Obsidian scanner budgets move in lockstep.
- Parse dashboard wizard uploads through _BoundedUploadRoute under the advertised ceiling: >1,000-file batches no longer fail inside Starlette's hidden 1,000-part default; oversized batches return a clean 413 and large vault uploads clear the 8 MB body limit.
- Surface folder-import truncation via truncated/matched_total/unreadable instead of silently importing an alphabetically-first slice.
- Degrade one unreadable/pathological file to a per-file error instead of rolling back the whole batch with a 500.
- Mark worker-dead import jobs failed (worker_lease_expired) on next status poll instead of reporting running forever.
- Hydrate OneDrive Files-On-Demand placeholders via new fsutil.is_link_indirection; symlinks and junctions remain blocked.
- Raise MAX_IMPORT_FILES 500 -> 1,500 and total bytes to 750 MB; document/Obsidian scanner budgets move in lockstep.
- Parse dashboard wizard uploads through _BoundedUploadRoute under the advertised ceiling: >1,000-file batches no longer fail inside Starlette's hidden 1,000-part default; oversized batches return a clean 413 and large vault uploads clear the 8 MB body limit.
- Surface folder-import truncation via truncated/matched_total/unreadable instead of silently importing an alphabetically-first slice.
- Degrade one unreadable/pathological file to a per-file error instead of rolling back the whole batch with a 500.
- Mark worker-dead import jobs failed (worker_lease_expired) on next status poll instead of reporting running forever.
- Hydrate OneDrive Files-On-Demand placeholders via new fsutil.is_link_indirection; symlinks and junctions remain blocked.
Thought synthesis default 512 -> 4096 tokens and availability ping 5 -> 1024: reasoning models spend completion budget on hidden reasoning tokens first, so tiny caps returned empty replies that read as false negatives.
Thought synthesis default 512 -> 4096 tokens and availability ping 5 -> 1024: reasoning models spend completion budget on hidden reasoning tokens first, so tiny caps returned empty replies that read as false negatives.
Eval fixtures seed via tempfile.TemporaryDirectory(), which lands under the runner tempdir — not under GITHUB_WORKSPACE/RUNNER_TEMP roots exported to pytest legs, so index_repo rejected them ('repo root is outside approved local roots'). Append tempfile.gettempdir() to ENGRAPHIS_INDEX_ROOTS on the three full-suite legs.
Eval fixtures seed via tempfile.TemporaryDirectory(), which lands under the runner tempdir — not under GITHUB_WORKSPACE/RUNNER_TEMP roots exported to pytest legs, so index_repo rejected them ('repo root is outside approved local roots'). Append tempfile.gettempdir() to ENGRAPHIS_INDEX_ROOTS on the three full-suite legs.
…oad test

- test_service: staticmethod wrapper is not callable on 3.9; patch the module attribute with a plain callable.
- test_remember_many: importorskip mcp so the numpy-only core floor skips instead of failing.
- test_bounded_uploads: assert the bounded route class on router.routes — newer FastAPI wraps included routers in one composite object instead of flattening per-path routes onto app.routes; also fix the too-many-fields payload (dict comprehension collapsed 64 fields to one key) and pin the strict 400 contract.
…oad test


- test_service: staticmethod wrapper is not callable on 3.9; patch the module attribute with a plain callable.
- test_remember_many: importorskip mcp so the numpy-only core floor skips instead of failing.
- test_bounded_uploads: assert the bounded route class on router.routes — newer FastAPI wraps included routers in one composite object instead of flattening per-path routes onto app.routes; also fix the too-many-fields payload (dict comprehension collapsed 64 fields to one key) and pin the strict 400 contract.
Raw str(ResourceExtractionError) reached import API responses (CodeQL py/stack-trace-exposure, 15 sinks in routes/v2_api.py). Reports now carry canned labels from core.documents._safe_reason; the full message stays in server logs only.
Raw str(ResourceExtractionError) reached import API responses (CodeQL py/stack-trace-exposure, 15 sinks in routes/v2_api.py). Reports now carry canned labels from core.documents._safe_reason; the full message stays in server logs only.
The dependency-free indexer only produced 'defines' edges, so on the numpy-only floor (no tree-sitter) the code-arm bridge could not hop a caller to its callee and code-arm recall collapsed to 0.0 (core-floor CI). The fallback now emits caller→callee 'calls' edges for references to same-file symbols inside detected function bodies — bounded to indexed symbol names, one edge per pair, best-effort by design; the AST backend stays authoritative where a grammar exists.
The dependency-free indexer only produced 'defines' edges, so on the numpy-only floor (no tree-sitter) the code-arm bridge could not hop a caller to its callee and code-arm recall collapsed to 0.0 (core-floor CI). The fallback now emits caller→callee 'calls' edges for references to same-file symbols inside detected function bodies — bounded to indexed symbol names, one edge per pair, best-effort by design; the AST backend stays authoritative where a grammar exists.
- Filter batch sibling context passed to resolution by matching memory type, mirroring _resolve_against_neighbors' own candidate visibility and scoring's per-type weights: a cross-type restatement can no longer drive ADD/NOOP/INVALIDATE.
- Derive per-fact trusted_write from the normalized provenance envelope (prompt_eligible) exactly like the single-write path: untrusted batches (api/web/import ingress) stay passive pending evidence instead of resolving against live memory or minting trusted hints.
- Queue post-commit vector publications only for ops that inserted a record (add/invalidate/relate); noop results reference the pre-existing memory id and must never republish a candidate vector over it.
- Revalidate session liveness inside the batch transaction via store.begin_session_write under the write lock, so a session ended between pre-checks and commit rejects cleanly instead of attaching writes.
- Filter batch sibling context passed to resolution by matching memory type, mirroring _resolve_against_neighbors' own candidate visibility and scoring's per-type weights: a cross-type restatement can no longer drive ADD/NOOP/INVALIDATE.
- Derive per-fact trusted_write from the normalized provenance envelope (prompt_eligible) exactly like the single-write path: untrusted batches (api/web/import ingress) stay passive pending evidence instead of resolving against live memory or minting trusted hints.
- Queue post-commit vector publications only for ops that inserted a record (add/invalidate/relate); noop results reference the pre-existing memory id and must never republish a candidate vector over it.
- Revalidate session liveness inside the batch transaction via store.begin_session_write under the write lock, so a session ended between pre-checks and commit rejects cleanly instead of attaching writes.
_recover_stale_import_jobs borrowed the graph-index 60s lease, so any single document taking longer than a minute (large PDF, OCR image, transcription) got killed by its own status poll mid-file. Imports now carry IMPORT_JOB_LEASE_SECONDS=900 while keeping the existing progress-aware expiry: the per-document heartbeat resets lease age, live workers are never failed, dead workers still expire with worker_lease_expired.
_recover_stale_import_jobs borrowed the graph-index 60s lease, so any single document taking longer than a minute (large PDF, OCR image, transcription) got killed by its own status poll mid-file. Imports now carry IMPORT_JOB_LEASE_SECONDS=900 while keeping the existing progress-aware expiry: the per-document heartbeat resets lease age, live workers are never failed, dead workers still expire with worker_lease_expired.
… status

- _consolidation_evidence now appends non-record endpoints of consolidates/profiles links through the visible-append gate, so legacy/repaired digests carrying sources only in the link tables still yield complete grounding evidence.
- scripts.sync --status --repo <name> scopes memory/tombstone counts to the requested repository (_scoped_counts); absent repos report an empty scope instead of workspace totals; no-repo invocations keep workspace-wide totals.
… status


- _consolidation_evidence now appends non-record endpoints of consolidates/profiles links through the visible-append gate, so legacy/repaired digests carrying sources only in the link tables still yield complete grounding evidence.
- scripts.sync --status --repo <name> scopes memory/tombstone counts to the requested repository (_scoped_counts); absent repos report an empty scope instead of workspace totals; no-repo invocations keep workspace-wide totals.
…hema, error routing

- sync --status --repo: a repository absent from the workspace now reports an explicitly empty scope ('repo: <name> (not found locally)', zero counts) and no longer presents the workspace checkpoint as the requested scope's cursor.
- mcp_server: the remember_many per-fact schema documents evidence_source and states the link predicate (subject_key or evidence_source) matching the engine, so schema-driven agents actually get wired siblings.
- cli: only MemoryService construction maps through _startup_error via a dedicated _ServiceStartupError marker; command-phase OSError/RuntimeError/etc. report honestly as command failures with a value-free strerror instead of advising engraphis-init --check for a directory argument.
…hema, error routing


- sync --status --repo: a repository absent from the workspace now reports an explicitly empty scope ('repo: <name> (not found locally)', zero counts) and no longer presents the workspace checkpoint as the requested scope's cursor.
- mcp_server: the remember_many per-fact schema documents evidence_source and states the link predicate (subject_key or evidence_source) matching the engine, so schema-driven agents actually get wired siblings.
- cli: only MemoryService construction maps through _startup_error via a dedicated _ServiceStartupError marker; command-phase OSError/RuntimeError/etc. report honestly as command failures with a value-free strerror instead of advising engraphis-init --check for a directory argument.
Bumps [openai-codex](https://github.com/openai/codex) from 0.144.4 to 0.147.0.
- [Commits](openai/codex@rust-v0.144.4...rust-v0.147.0)

---
updated-dependencies:
- dependency-name: openai-codex
  dependency-version: 0.147.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Coding-Dev-Tools and others added 14 commits November 1, 2026 03:51
Guard the security-relevant ENGRAPHIS_BROWSER_AUTO_SESSION default (on) and its
off switches, including the malformed-value fallback. The configuration and
Playwright comments now describe the shipped behavior: token-protected API
routes, automatic browser access.

Co-authored-by: coding-dev-tools <coding-dev-tools@users.noreply.github.com>
Guard the security-relevant ENGRAPHIS_BROWSER_AUTO_SESSION default (on) and its
off switches, including the malformed-value fallback. The configuration and
Playwright comments now describe the shipped behavior: token-protected API
routes, automatic browser access.
- Lead the Jev section with "included free with every paid plan: Pro and Team"
- Keep the entitlement, rolling limits, fleet guard, consent, and BYOK terms intact
- Record the clarification under Unreleased

Co-authored-by: coding-dev-tools <coding-dev-tools@users.noreply.github.com>
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- Lead the Jev section with "included free with every paid plan: Pro and Team"
- Keep the entitlement, rolling limits, fleet guard, consent, and BYOK terms intact
- Record the clarification under Unreleased
* docs(plans): include 500 free Jev calls per day for Pro and Team

- Replace the three rolling caps with one free 500-call daily allowance
- State the included allowance in the README, plan comparison, configuration,
  MCP reference, bundled skill, env sample, and dashboard messages
- Update the documentation contract to pin the policy; historical 1.7.9 notes stay unchanged

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

* docs(plans): announce managed Jev availability for paid plans

- Replace the not-yet-available notice with live availability and enablement
- Keep the 500-call daily allowance and per-call consent rules
- Refresh the bundled skill checksum

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

---------

Co-authored-by: coding-dev-tools <coding-dev-tools@users.noreply.github.com>
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
* docs(plans): include 500 free Jev calls per day for Pro and Team

- Replace the three rolling caps with one free 500-call daily allowance
- State the included allowance in the README, plan comparison, configuration,
  MCP reference, bundled skill, env sample, and dashboard messages
- Update the documentation contract to pin the policy; historical 1.7.9 notes stay unchanged


* docs(plans): announce managed Jev availability for paid plans

- Replace the not-yet-available notice with live availability and enablement
- Keep the 500-call daily allowance and per-call consent rules
- Refresh the bundled skill checksum


---------
* chore(release): prepare 1.7.12 candidate

- Bump package, plugin, and commercial-manifest versions to 1.7.12
- Record the 1.7.12 changelog entry for automatic browser access, the salvaged
  verification tooling, and dependency/CI upkeep
- Refresh Claude plugin asset checksums

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

* docs(readme): state Jev is free for Pro and Team up front

- Lead the Jev section with "included free with every paid plan: Pro and Team"
- Keep the entitlement, rolling limits, fleet guard, consent, and BYOK terms intact
- Record the clarification under Unreleased

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

* fix(sync,manifest): record sync authorization denial and support public-offer cloud contract

- Record authoritative entitlement denial when POST /api/sync/run fails with 401/402/403, and return account_url() when connected to prevent lapsed Team users from misrouting to Pro checkout
- Accept schema 'engraphis-public-offer/v1' in scripts/check_commercial_manifest.py --cloud-contract to cleanly validate against engraphis-cloud
- Add regression test in tests/test_sync_dashboard.py

Agent: antigravity

* fix(benchmark,eval): isolate offline chunking eval and refresh 1.7.12 release evidence

- Ensure chunking_eval uses retention_supervisor=none so offline evaluations
  remain deterministic and independent of local user LLM retention settings
- Export fresh immutable offline evidence artifact for 1.7.12 release
- Update benchmark report images (SVG and PNG provenance chunks)
- Bind new fixture digest and artifact sha256 across tests and documentation

Agent: antigravity

---------

Co-authored-by: coding-dev-tools <coding-dev-tools@users.noreply.github.com>
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
* chore(release): prepare 1.7.12 candidate

- Bump package, plugin, and commercial-manifest versions to 1.7.12
- Record the 1.7.12 changelog entry for automatic browser access, the salvaged
  verification tooling, and dependency/CI upkeep
- Refresh Claude plugin asset checksums


* docs(readme): state Jev is free for Pro and Team up front

- Lead the Jev section with "included free with every paid plan: Pro and Team"
- Keep the entitlement, rolling limits, fleet guard, consent, and BYOK terms intact
- Record the clarification under Unreleased


* fix(sync,manifest): record sync authorization denial and support public-offer cloud contract

- Record authoritative entitlement denial when POST /api/sync/run fails with 401/402/403, and return account_url() when connected to prevent lapsed Team users from misrouting to Pro checkout
- Accept schema 'engraphis-public-offer/v1' in scripts/check_commercial_manifest.py --cloud-contract to cleanly validate against engraphis-cloud
- Add regression test in tests/test_sync_dashboard.py

Agent: antigravity

* fix(benchmark,eval): isolate offline chunking eval and refresh 1.7.12 release evidence

- Ensure chunking_eval uses retention_supervisor=none so offline evaluations
  remain deterministic and independent of local user LLM retention settings
- Export fresh immutable offline evidence artifact for 1.7.12 release
- Update benchmark report images (SVG and PNG provenance chunks)
- Bind new fixture digest and artifact sha256 across tests and documentation

Agent: antigravity

---------
An owner-private ~/.engraphis/config.env can enable live extraction,
retention supervision, or a BYOK decision backend. The autouse fixture
already pins paths, models, and cloud credentials; also pin the provider
features and remove provider key variables so the documented offline gate
cannot block on a live DNS lookup. Tests that exercise these paths opt in
explicitly with monkeypatch.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
An owner-private ~/.engraphis/config.env can enable live extraction,
retention supervision, or a BYOK decision backend. The autouse fixture
already pins paths, models, and cloud credentials; also pin the provider
features and remove provider key variables so the documented offline gate
cannot block on a live DNS lookup. Tests that exercise these paths opt in
explicitly with monkeypatch.
CVE-2026-115557 in the Python 3.11.17 runtime is fixed in 3.11.18.
Pin the new multi-arch digest so the release grype gate can pass.

Co-authored-by: coding-dev-tools <coding-dev-tools@users.noreply.github.com>
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
CVE-2026-115557 in the Python 3.11.17 runtime is fixed in 3.11.18.
Pin the new multi-arch digest so the release grype gate can pass.
Main was replayed onto the release lineage; the trees differ only by the
Python base-image update. Merge the new lineage so the PR has a valid merge
base without rewriting the branch.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Main was replayed onto the release lineage; the trees differ only by the
Python base-image update. Merge the new lineage so the PR has a valid merge
base without rewriting the branch.
@chatgpt-codex-connector

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 ⚠️ Failed 2026-11-04T06:02:19.395878Z
We couldn’t complete this review. Comment @codex review to try again.
8674c49 PR opened
ℹ️ 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

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Coding-Dev-Tools
Coding-Dev-Tools force-pushed the main branch 2 times, most recently from 3d330e8 to 8ef46b6 Compare November 4, 2026 06:12
Coding-Dev-Tools and others added 3 commits November 4, 2026 18:44
## Why upgrade to Pro or Team in the README

- Adds a prominent upgrade section after the local feature list.
- Explains memory health analytics, scheduled upkeep, encrypted sync, team roles/audit, and the included Jev allowance.
- Shows how Jev helps agentic memory: safe vs risky actions, contradictory vs reinforcing memories, supported vs unsupported answers, and complete vs unfinished work.
- Adds pricing, no-card trial details, comparison link, and Pro/Team signup links.

Tests: documentation contracts, Pro CTA, plugin distribution, and skill package pass; ruff clean.
Bring the branch current with main.
Bring the branch current with main.
@Coding-Dev-Tools
Coding-Dev-Tools force-pushed the test/offline-suite-isolation branch from a59014b to 22a6db8 Compare November 5, 2026 07:07
@Coding-Dev-Tools
Coding-Dev-Tools deleted the branch main-tmp November 5, 2026 07:22
@Coding-Dev-Tools
Coding-Dev-Tools changed the base branch from main-tmp to main November 5, 2026 07:23
Deleting provider environment variables is not enough because Settings is
materialized at import; an owner's live LLM/BYOK credentials remain on the
singleton and LLMClient still connects. Pin the provider fields too and add
a contract test that asserts the offline defaults and the scrubbed env.
Keep the provider-credential pinning and contract test on top of the
rebased remote head.
@Coding-Dev-Tools
Coding-Dev-Tools merged commit 99112a3 into main Nov 5, 2026
29 checks passed
@Coding-Dev-Tools
Coding-Dev-Tools deleted the test/offline-suite-isolation branch November 5, 2026 08:14
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