Skip to content

v1.1.8

Choose a tag to compare

@nikolanovoselec nikolanovoselec released this 20 May 06:27
· 98 commits to main since this release
970857c

Knowledge-Graph Context, Persistent Vault + SilverBullet, Vault Encryption, Sync v2, SDD Skill Split

Agent coverage. Everything described here (model tiers, hooks, skills, rules, MCP plumbing, graphify integration) is currently optimized for the Claude Code session shape - skill/hook/rule conventions, named-subagent dispatch, the opus/sonnet/haiku tier ladder, and mcp__* tool surfaces. As other coding agents (Codex, Gemini, Copilot, OpenCode, etc.) expose comparable extension points, the same capabilities will be ported over in a session-shape-appropriate form. The container does not lock you out of running a different agent, but the discipline layer and cost-tuning only apply to Claude Code sessions today.

Vault & SilverBullet

Persistent vault subsystem with in-browser SilverBullet editor (#366, REQ-VAULT-001..007)

New /home/user/Vault/ synced via rclone bisync, edited live in the browser through a SilverBullet 2.8.0 instance reverse-proxied through the Worker. Captures both agent-written session notes and user-curated prose, surfaces them in a unified graphify graph alongside per-repo graphify-out/.

  • Layout. Raw/Sessions/ (agent-owned), Notes/ (user-owned), graphify-out/ (per-vault graph), .silverbullet/ (editor config).
  • Editor. SilverBullet binary baked into the container image (Dockerfile pin + SHA), supervised loop in entrypoint.sh, bound to 127.0.0.1:3030.
  • Proxy. src/routes/vault.ts mirrors the terminal proxy chain (auth, origin, tier, rate-limit, container-health) plus WebSocket upgrade passthrough for live-edit sync.
  • Subpath hosting. SilverBullet has no per-session SB_URL_PREFIX knob, so the Worker rewrites <base href="/" /> -> <base href="/api/vault/{sid}/" /> on the shell HTML response. content-length + content-encoding dropped because Workers auto-decompress.
  • Persistence. rclone bisync filter + Vault/** overrides the global graphify-out/** exclude. Shutdown bisync wrapped in timeout 60; container destroy() budget raised 25s -> 75s.
  • Capture path. memory-capture.sh UserPromptSubmit hook writes markdown into Raw/Sessions/{iso-ts}-{sid}.md every 15 prompts, then flock graphify global add merges into ~/.graphify/global-graph.json.
  • Extract path. vault-monitor daemon detects user edits (60s mtime poll, two-marker high-water pattern); vault-monitor-hook.sh UserPromptSubmit hook spawns a background subagent that runs single-file graphify extraction.

Vault encryption, attachment uploads, monotonic vault graph (#385, REQ-VAULT-008/009, REQ-MEM-009, AD58, AD59)

  • Zero-UI vault encryption (REQ-VAULT-008, AD59) - per-session vault key minted by the Container DO and injected into SilverBullet's BootConfig over the existing authenticated channel; no passphrase UI. Raw/Pasted/** lazy-loaded; graphify-out/** and other agent-owned paths excluded server-side; treeview matches. Aggressive cleanup on session DELETE; orphan-IDB sweep on Dashboard mount. AD59 threat model: per-session DO-storage key defeats offline disk attacks (profile theft, backup leak, ransomware scanning); explicit non-goal is defeating anyone with an authenticated browser tab.
  • Attachment uploads (REQ-VAULT-009) - drag-drop PDFs and images into a note. Same-origin fallback for state-changing vault writes; PUT/POST/PATCH travel the same auth chain as reads.
  • Monotonic vault graph (REQ-MEM-009) - vault-extract maintains a persistent vault-graph.json and merges each extraction via hash-keyed union; graphify global add --as user_vault publishes the cumulative state instead of clobbering it on every run. Step 6 of the vault-extract contract re-renders vault-graph.html after each merge (was static and stale).
  • Global graph HTML viz dropped - the unified graph is a 10k+ node corpus that renders as an unusable hairball; mcp__graphify__* is the real interface. Entrypoint includes one-time cleanup for legacy installs.

Vault button readiness + no-give-up recovery (AD55, REQ-VAULT-012 AC5)

Layout.tsx gates the vault button on a ground-truth HEAD /api/vault/:sid/ probe with per-session latch and a steady-state re-probe that catches SilverBullet crashing mid-session. PR #414 then rewrote the probe as a pure state machine in web-ui/src/lib/vault-readiness.ts - warmup at 5s cadence retrying until first success, steady at 60s with fall-back-to-warmup on failure. Eliminates the failure mode where a 2h idle stop made SilverBullet take longer than the prior 60-attempt warmup cap and left the button permanently disabled. 5 regression tests pin the no-give-up behaviour, latch-on-success, SilverBullet-crash recovery, cancel correctness, and mid-probe cancellation.

Vault bootstrap-hop encryption-flag race (#414)

localStorage.setItem("enableEncryption","true") was firing BEFORE awaiting navigator.serviceWorker.register(). A tab close between the setItem and the await resolving left the flag durably true with no SW key; the next bootstrap then booted SilverBullet expecting encrypted IDB it could not read. Reordered so the flag, cookie, and redirect all live in the post-handoff success branch; tests pin the new ordering on both failure branches.

Memory & capture

MCP server-memory removal (#366)

  • mcp__memory__* tools deregistered (entrypoint MCP config cleared of the server-memory entry). The JSONL graph at ~/.memory/ and the entire tool surface are gone.
  • Vault is now the sole long-term memory store; mcp__graphify__* is the sole query interface.
  • sdd/memory.md, documentation/memory.md, and preseed/agents/claude/rules/memory.md rewritten end-to-end so agents query via mcp__graphify__*.

Capture pipeline v2 + agent cost cuts (#385, #382, AD58)

  • Capture pipeline v2: sonnet + prefilter + scratchpad. 15-prompt batches now use sonnet (replacing haiku, which confabulated adjacent REQ/ADR IDs in benchmarks) with a transcript prefilter that strips tool I/O and a chunked-scratchpad pass for higher-fidelity observations. Inline-Python graph build (graphify.build / graphify.cluster / graphify.export.to_json) under flock -w 5.
  • memory-capture + vault-extract downgraded to haiku at the named-subagent level (templated structured-extraction; ~1/8 the cost of sonnet). The higher-stakes fidelity work stays pinned to sonnet so the dispatching parent cannot silently downgrade.
  • spec-reviewer downgraded opus -> sonnet. Net per-PR review cost ~60-70% lower than three opus runs without measurably sacrificing review quality.

Browser timezone auto-sync + USER_TIMEZONE wiring (#385, #395, REQ-MEM-001 AC3, REQ-SESSION-016 AC5)

  • Dashboard reads the browser's IANA zone on mount and silently PATCHes userTimezone against /api/preferences with runtime IANA-zone validation.
  • Durable Object handleSetBucketName destructures + types + forwards userTimezone through setBucketName and applyPrefsOnRestart; normalizeIanaTz boundary validation at module level with persist-before-mutate ordering. HTTP-level regression tests pin the surface end-to-end.
  • Entrypoint applies TZ / /etc/timezone / /etc/localtime before any logging fires. Capture filenames in Raw/Sessions/ reflect local wall-clock time.

Memory-capture ISO_TS confabulation + ephemeral-disk resume detection (#414, closes #416, REQ-MEM-002 AC6, REQ-MEM-010 AC5/AC6/AC7)

The LLM-generated capture-file timestamps were inventing T00-00-00+0000 / T12-00-00+0000 / T23-30-00+0000 instead of executing date '+%Y-%m-%dT%H-%M-%S%z'. Forced derivation through Bash in memory-agent-prompt.md; extracted Step 1.5 into assert-iso-ts.sh (preseeded, manifest-registered, 5 behavioural tests via spawnSync + override seam). REQ-MEM-010 AC5/AC6/AC7 split out to pin the no-confabulation guarantee.

  • Resume detection rebuilt off Cloudflare Containers' ephemeral-disk contract. Counter relocated from ~/.memory/counter/ (synced to R2, survives) to /tmp/.memory-counter/ (verified ephemeral per upstream docs: "All disk is ephemeral... a fresh disk as defined by its container image"). Counter absence on the first hook fire of a new container instance is the canonical "this is a fresh container, treat as resumed" signal - no mtime threshold, no SessionStart hook plumbing, no transcript scanning.
  • CURRENT_COUNT > 1 distinguishes brand-new sessions (1 user prompt) from resumed sessions (transcript restored on disk with prior-session prompts). Resumed sessions force-fire a capture covering the transcript tail.
  • Reference doc added at ~/Vault/References/Cloudflare-Containers-Ephemerality.md with verified upstream quotes.

Knowledge graph (graphify)

Knowledge-graph context for AI agents (#354, REQ-AGENT-023, AD52, AD53)

Integrates the upstream graphify (graphifyy on PyPI, Apache-2.0) so agents navigate codebases structurally instead of grep-storming. query_graph, get_node, get_neighbors, shortest_path, and the three repo-aware tools are ambient capability across both default and advanced session modes. The MCP server and hot-reload wrapper are wired into Claude Code sessions today; the underlying graph.json + CLI are agent-agnostic, so equivalent wiring for other agents (Codex, Gemini, Copilot, OpenCode) will follow as their MCP / tool-extension surfaces stabilize.

  • Container install at build time. uv tool install graphifyy[mcp,sql,pdf]==$VER pinned in preseed/agents/claude/plugins/graphify/.claude-plugin/plugin.json. ~220 MB image cost paid once at build, not per session.
  • Hot-reload wrapper (AD53). graphify-mcp-lazy.py monkey-patches graphify.serve._load_graph to return a LazyGraph (nx.DiGraph subclass) that starts empty and refreshes from disk on a daemon watcher thread. Rebind uses an atomic _node/_adj/_pred/_succ/graph dict-pointer swap under a single critical section, so concurrent tool-handler reads never see a half-swapped graph. Container starts empty, user clones a repo mid-session, the wrapper picks up graphify-out/graph.json within GRAPHIFY_POLL_SECONDS (default 2s).
  • Active-repo tracking (advanced only). PostToolUse hook graphify-active-repo.sh writes the agent's current repo root to ~/.cache/codeflare-hooks/graphify-active-cwd. Matchers cover Bash (flag-aware git clone / gh repo clone target extraction), Edit/Write/Read/NotebookEdit (walk-up from file_path), and mcp__context-mode__ctx_execute* (parses cd targets out of the shell payload). Wrapper consults the sentinel first, falls back to freshest-mtime.
  • Advanced discipline layer. graph-first.md rule + four hooks - SessionStart injects context if graphify-out/graph.json exists; PostToolUse on git clone/gh repo clone prompts for build or recommends graphify update; PreToolUse on Grep/Glob + mcp__context-mode__ctx_search/ctx_batch_execute soft-nudges toward mcp__graphify__* when a graph exists. Non-blocking.
  • Git as the persistence layer. R2 bisync excludes graphify-out/ entirely. Repos commit graph.json + GRAPH_REPORT.md + small metadata; the working tree gets them on clone.
  • Semantic merge driver registered globally (git config --global merge.graphify.driver). Repos that wire graphify-out/graph.json merge=graphify in .gitattributes get auto-resolution of concurrent graph.json edits.
  • Tier-gating (AD52). MCP server + CLI + hot-reload wrapper ship to default and advanced; hooks + rule + SKILL ship to advanced only.

/graphify skill: mandatory build-mode + haiku subagents + gitignore (#383)

  • Before dispatching Part B semantic subagents, the agent MUST present an AskUserQuestion with exactly two modes (AST-only free, or Full AST + haiku semantic) including the actual subagent count and a wall-time estimate. Eliminates the silent-skip path where extraction ran or didn't run without the user choosing.
  • Subagents pinned to model: "haiku" so per-build cost matches vault-extract economics (~1/8 of opus, ~1/3 of sonnet). --mode deep may escalate to sonnet, never opus.
  • .gitignore guidance expanded from 2 patterns to 11: graphify-out/cache/, graphify-out/manifest.json, 9 .graphify_* scratch files, and graphify-out/obsidian/ (auto-generated Obsidian stub vault, ~2300 files on a medium repo, rewrites centrality + community frontmatter every update). Post-change git add graphify-out/ produces 4 essential files instead of 2514.

Graphify hard-block hook (#366, REQ-AGENT-024)

PreToolUse hook enforce-graphify.sh denies grep-class searches after 3 in a turn without a mcp__graphify__* or graphify query call. Complements the existing soft nudge.

  • Matcher set: Grep, Bash, mcp__context-mode__ctx_execute*.
  • Classifier: grep|rg|ag|ack, git grep, find -name/-path/-iname/-ipath/-regex, awk /regex/.
  • Reuses extract_subs + normalize_command from enforce-ctx-mode.sh (segment splitter + flag-aware tokeniser).
  • User-only bypass: touch /tmp/graphify-bypass (one-shot, auto-deleted) or "skip graph" in a user message.

Graphify pin 0.8.16 -> 0.8.18 (#414)

Two upstream releases land. v0.8.17 fixes a phantom-edge bug in case-sensitive call resolution for Go / Rust / Elixir / Ruby / C# / Java / Kotlin / Scala (the generic resolver previously lowercased both sides of the label index, producing inferred calls edges that did not exist in the source). v0.8.18 adds semantic context tags on references edges (parameter_type, return_type, generic_arg, attribute, field) for Python / JS / TS / C# / Java, splits inherits/implements for C#/Java, and fixes post-commit hook updates after delete-only commits. Breaking change is Java-only (extends edge rename); does not affect codeflare's own graph. Codeflare is a platform - these wins land for every user who brings non-TS code, not just the codeflare repo itself.

Container & runtime infrastructure

Sync v2 (#385, #384, REQ-STOR-003 / REQ-STOR-005 / REQ-STOR-015)

  • 15-minute idle cadence (down from the previous 60-second hammer) with interruptible sleep, breathing UI on the sync button, no-session notice, and a portable timezone-aware schedule.
  • 135-second shutdown budget. Bisync filter file with vanishing-file recovery and 3-failure --resync fallback.
  • Per-session sync trigger UI; fan-out with concurrency cap and per-session failure isolation.
  • Workspace excluded from sync by default; rationale in documentation/storage-and-sync.md.

/dev/shm cold-boot mount (#414, REQ-AGENT-023 prereq)

Firecracker microVM rootfs ships without the /dev/shm mountpoint directory. Python's multiprocessing.Lock (graphify AST extractor, memory-capture chunker, vault-extract writer) needs POSIX shared memory there. Entrypoint creates the dir + mounts tmpfs on cold boot, idempotent on warm boot, hard-exits on mount failure so daemon crashes surface at boot instead of cryptic synchronize.py:57 mid-session. Behavioural test spawns a real Python ProcessPoolExecutor and asserts [1, 2, 3].

context-mode@1.0.151 pin + watchdog/bypass-default revert (#414)

  • Plugin pinned to v1.0.151 (bump from 1.0.118). Carries the upstream issue #671 fix - synchronous better-sqlite3 calls were blocking the Node event loop on long-lived FTS5 indexes, burning a whole vCPU. Regression sentinel test asserts the version floor.
  • Watchdog + bypass-default reverted. An earlier mitigation that SIGKILLed the context-mode MCP server on FTS5 bloat was wrong on two counts: Claude Code owns the stdio transport and does not respawn it (kill = MCP dead until full client restart, strictly worse than the symptom), and v1.0.151 already fixes the upstream bug. Routing-default touch /tmp/ctx-bypass at boot also reverted - routing is active by default from session start; the sentinel remains a user-only escape hatch via enforce-ctx-mode.sh.

block-local-builds.sh regex bypass (#414)

POSIX bracket expression [^\n] was literal backslash + n, not "non-newline", so npx --no-install vitest, npx -y oxlint, and similar flag-prefixed invocations bypassed the PreToolUse hook entirely. Fixed pattern and added 6 regression tests for the bypass class.

SDD framework, review & documentation

SDD rule-skill split + /review --deep + scope flags (#335, closes #333)

Refactors the SDD discipline rules into a core-rule + on-demand-skill pattern, halving per-PR rule token cost while preserving full behaviour.

  • SDD enforcement skill family (7 new skills): spec-enforce, spec-enforce-ac, spec-enforce-truth, doc-enforce, doc-enforce-lanes, doc-enforce-shape, doc-enforce-truth. Detection algorithms, manifest execution, splitting mechanics, content-quality checks moved out of the always-loaded rule files into skills invoked on PR-boundary triggers.
  • Discipline rules trimmed - spec-discipline.md (120 L), documentation-discipline.md (85 L), tdd-discipline.md (56 L) reduced to identity + status vocabulary + severity + skill pointer. tdd-enforce skill carries the 8-antipattern catalogue.
  • git-workflow umbrella merges git-workflow + ci-monitoring + deploy-credentials into one core rule that branches to 4 skills (ci-monitoring, git-review-pipeline, pr-workflow, deploy-credentials).
  • /review --all / --diff scope flags aligned with /sdd clean. CLI help screen when invoked without arguments.
  • /review --deep + Phase 3 behavioral verification - new deep-reviewer agent. Phase 3 spawns ceil(N/15) parallel deep-reviewers partitioned by impl-file locality, judging spec-vs-impl behavioral match per AC. Findings flow into the canonical/triage pipeline. Phase numbering renumbered: old 3-10 become 4-11.
  • Per-sub-command SDD skills - spec-driven-development split into sdd-init, sdd-clean, plus the spec-enforce and doc-enforce families. Commands trimmed to dispatch shells; rule auto-load surface reduced ~60%.

Lane-gated review spawning (#385, #395, REQ-AGENT-021 AC7, REQ-AGENT-025)

  • PostToolUse nudge and Stop hook share scripts/lib/lane-classifier.sh: a doc-only push spawns only doc-updater; an sdd/ push spawns spec-reviewer then doc-updater; any source touch spawns all three.
  • Conservative branches (empty diff, missing prior ack, divergent merge-base) and a missing or unsourceable helper fall back to all-three-lanes (fail-closed).
  • Stop hook recognises gh pr merge PUSH_LINE across all three tool surfaces (Bash, mcp__*__ctx_batch_execute, mcp__*__ctx_execute with language=shell) so server-side merges advance the ack pointer.
  • Graphify-first review. mcp__graphify__* replaces grep for structural questions across code-reviewer, spec-reviewer, doc-updater, deep-reviewer, security-reviewer, refactor-cleaner, tdd-guide, architect.
  • Eight review agents harmonized. Section order, conditional invocation, graph-first integration, cross-session signals, deduped boilerplate.

Always-loaded rules trim + review-bypass sentinel hardening (#395, #366)

  • spec-discipline.md, documentation-discipline.md, karpathy.md, tdd-discipline.md compacted ~48% (169 -> 88 lines). Bulk content moved into the load-on-trigger skills that already own it; 1-2 line keepsakes inline preserve mid-task functionality.
  • sdd/.skip-next-review (committable, survived session restart) replaced by /tmp/review-bypass (per-session, never committed, auto-deleted on use). Updated in enforce-review-spawn.sh, the SDD skill, and the memory rule.

SDD-clean migration: depoperationalization + layout flat -> nested (#414)

215 REQs swept across 12 domain files (TERM / SESSION / SEC / OPS / MOBILE / AGENT / AUTH / SUB / MEM / VAULT / STOR). Test-theater excised lane-by-lane; real @test anchors backfilled with describe-block + AC traceability. ACs and Constraints stripped of implementation leakage (function signatures, env var literals, KV key shapes, file paths, JS expressions, route paths) and lifted to principle-state language. Spec ended at 214 Implemented + 1 Partial (REQ-AGENT-024). Three follow-up review rounds cleared every CRITICAL / HIGH / MEDIUM plus all reviewer LOWs. Layout migrated from flat sdd/*.md to nested sdd/spec/*.md. Worker-runtime tests excised from src/__tests__/ (cannot readFileSync in Worker target); oxlint + tsc errors resolved.

Documentation anchor-link sweep (#414)

  • 87 short-form REQ anchor links (#req-x-n) rewritten to GitHub-rendered full-title slugs (#req-x-n-full-title-slug) across documentation/lanes/api-reference.md (40), configuration.md (38), and 7 other lane files. Short-form anchors do not resolve under GitHub's slug algorithm.
  • 13 pre-existing broken anchors fixed: AD18/AD37 slug corrections, container-do -> container-do-container, AD7 (merged into AD10) repointed, vault.md internal AD54/AD55 fixed to point at decisions/README.md, dead Timekeeper-DO / sleep-timer / r2-sync-issues anchors stripped, REQ-AGENT-035 / CON-REL-001 / REQ-STOR-015 / visibility-return-reset slug corrections.
  • New doc-enforce-shape rule (Implements-column link rule, MEDIUM severity) added to prevent regression.

Reviewer findings cleared (PR #414 follow-ups)

  • REQ-VAULT-013 AC5/AC7: rewrote stale "static no-op SW" claim to match shipped VAULT_KEY_SHIM_SERVICE_WORKER_JS; AC7 no longer claims "zero user data / identical across sessions" since the SW receives a per-session key via postMessage.
  • REQ-VAULT-008 @impl: added anchors for VAULT_KEY_SHIM_SERVICE_WORKER_JS and VAULT_BOOTSTRAP_COOKIE.
  • REQ-VAULT-015 @impl: tightened module-level anchors to symbol-level (filterVaultFsListing, injectVaultIdbRecorder, VAULT_IDB_RECORDER_MARKER, cleanupSessionVaultCache, sweepOrphanVaultCaches).
  • 127 prior [sdd-clean] commits on the develop branch landed without spec-enforce: ran (anchors verified ...) / doc-enforce: ran (anchors verified ...) audit lines in their commit bodies. The skills did run (CQ-SOURCE evidence + .review-queue.md confirms it), but the tokens were omitted; rewriting history to backfill is destructive and not worth it for a one-time bulk-op surface. Tracked as a known limitation in sdd/spec/changes.md.

Product, tutorials, tests

Tutorial refresh + dead-asset cleanup (#382)

  • All four preseeded tutorial files refreshed to reflect the current product surface: Vault (SilverBullet notes), voice input, knowledge graph (graphify), /sdd//review//debug//deploy//brainstorm slash commands, auto review agents, advanced session mode, configurable auto-sleep, Fast Start, usage dashboard, /review flag matrix.
  • preseed/tutorials/Assets/ removed (30 SVG icons that no tutorial referenced and shipped to every new R2 bucket as dead weight). src/lib/tutorial-seed.generated.ts regenerated from 37 -> 7 documents. Existing buckets keep their Assets/ until the user deletes it - no migration.
  • SilverBullet theme retargeted from the inert --cf-* namespace to SB's actual variable namespace (--root-*, --ui-accent-*, --top-*, --button-*, --editor-*, --modal-*, --panel-*, --editor-wiki-link-*) under html[data-theme="dark"], verified against client/styles/theme.scss in the SilverBullet 2.8.0 source.

Retroactive AC test backfill (#386)

Tests added for REQ-STOR-003, REQ-STOR-005, REQ-STOR-015, REQ-MEM-001, REQ-MEM-004, REQ-MEM-006 so the implemented ACs have automated verification on every CI run.

CI / deploy / supply chain

CI / supply chain hardening (#385)

  • Deploy workflow_run hardening. deploy.yml if: now requires workflow_run.event == 'push' AND head_repository.full_name == github.repository. Defeats the public-repo pwn-request vector where a fork PR with a head branch named main could satisfy branches: [main] and trigger a deploy job that checks out untrusted code with actions: write + deploy-secret access. Closes Scorecard alert #34 (DangerousWorkflowID, CRITICAL). Codified as a Supply-chain constraint row in sdd/constraints.md.
  • yaml dep bump (web-ui). Added overrides: { yaml: ^2.8.3 } so transitive devDeps (knip, vite) resolve to yaml@2.9.0. Closes Scorecard alert #31 (GHSA-48c2-rrv3-qjmp).
  • bump-shadow-pins.yml actions SHA-pinned - actions/checkout and actions/setup-node upgraded from unpinned @v5 to SHA-pinned @v6. Closes Scorecard alerts #46, #45.
  • CodeQL #51 and #52 (js/shell-command-injection-from-environment in host/__tests__/lane-classifier.test.js) closed by switching from bash -c <script> to stdin-fed bash -s -- LIB SHA1 SHA2.
  • CodeQL #54 (PR #414): full regex-metacharacter escape in memory-capture-block.test.js sanitization.

BuildKit gha cache + raised deploy timeout (#359)

  • timeout-minutes: 20 -> 30 on both deploy.yml and deploy-dockerhub.yml. AD52's graphify addition pushed the deploy job past the old 20-minute cap.
  • BuildKit type=gha cache wired into both workflows. docker/setup-buildx-action@v3.12.0 (SHA-pinned) provisions a docker-container driver builder; docker build -> docker buildx build --cache-from type=gha --cache-to type=gha,mode=max --load. --load keeps the image in the local docker daemon so Trivy + wrangler push + docker push steps work unchanged. actions: write permission added for cache export.
  • Per-workflow cache scopes (scope=cloudflare / scope=dockerhub) so the two workflows never race on a shared cache key.

Docker Hub deploy as registry bypass (#355, #356)

New .github/workflows/deploy-dockerhub.yml, manual-dispatch only. Pushes container image to Docker Hub instead of registry.cloudflare.com, then runs the same wrangler deploy. OCI labels connect the published package to the source repo. GHCR variant was attempted first (#355) and confirmed dead-end: Cloudflare Containers rejected ghcr.io with IMAGE_REGISTRY_NOT_CONFIGURED. Docker Hub is on CF's supported list.

REQ-SEC-017 r2-nuke runbook + deploy.yml env dedup (#414)

deploy.yml r2-nuke step env: dedup fixed (duplicate env: blocks were breaking workflow_dispatch with HTTP 422); abort semantics + operator runbook documented in documentation/lanes/security.md.

Spec coverage

New REQs: REQ-VAULT-001..007 (vault subsystem), REQ-VAULT-008 (zero-UI vault encryption), REQ-VAULT-009 (attachment uploads), REQ-MEM-009 (monotonic vault graph), REQ-SESSION-016 (browser timezone), REQ-AGENT-023 (graphify integration), REQ-AGENT-024 (graphify hard-block hook), REQ-AGENT-025 (lane-gated review spawning), REQ-SEC-017 (r2-nuke runbook).

New AC splits (via PR #414): REQ-MEM-002 AC6 (ephemeral-disk resume signal), REQ-MEM-010 AC5/AC6/AC7 (Bash-forced ISO_TS, no-confabulation guarantee), REQ-VAULT-012 AC5 (vault-button no-give-up state machine).

New ADRs: AD52 (graphify tier-gating split), AD53 (hot-reload wrapper + active-repo tracking), AD55 (vault button readiness probe), AD58 (capture and vault-extract sonnet pinning), AD59 (zero-UI vault encryption threat model).

Dependencies (Dependabot bumps cumulative since v1.1.7)

  • @cloudflare/containers 0.3.3 -> 0.3.4 (#348)
  • oxlint 1.63.0 -> 1.64.0 root + web-ui (#347)
  • vitest 4.1.5 -> 4.1.6 root (#338) and web-ui (#345)
  • @types/node 25.6.0 -> 25.7.0 host (#344)
  • puppeteer 24.42.0 -> 24.43.1 (#343)
  • fast-check 4.7.0 -> 4.8.0 host (#341) and web-ui (#342)
  • github/codeql-action 4.35.3 -> 4.35.4 (#340)
  • vite 8.0.10 -> 8.0.12 web-ui (#339)
  • ws 8.20.0 -> 8.20.1 host (#337)
  • actions/dependency-review-action 4.9.0 -> 5.0.0 (#336)
  • context-mode shadow pin bumps via the weekly auto-bump workflow
  • context-mode 1.0.118 -> 1.0.151 (PR #414, upstream issue #671 fix)
  • graphifyy 0.8.16 -> 0.8.18 (PR #414, phantom-edge fix for 8 language ecosystems + semantic edge tags for Python/JS/TS/C#/Java)

CVE remediation

Suppressed in .trivyignore with explicit exposure-profile justification matching the established convention.

  • CVE-2026-6276 (curl / libcurl3-gnutls / libcurl4 7.88.1-10+deb12u14) - cookie leak via connection reuse with different credentials. Container uses curl exclusively for outbound HTTPS to fixed trusted endpoints; no multi-tenant cookie state. No fix in Debian bookworm.
  • CVE-2026-45186 (libexpat1 2.5.0-1+deb12u2) - computational complexity DoS on crafted XML attribute names. Transitive dep of git/python3; container parses no untrusted XML at runtime.
  • CVE-2026-44973 (go-git/go-billy/v5 v5.6.2 in lazygit v0.60.0) - path traversal via symlink-followed file ops. lazygit runs only against the user's own trusted local repos cloned via HTTPS.
  • CVE-2026-5773 (curl SMB connection reuse) - SMB protocol never invoked in the container.
  • CVE-2025-59375 (libexpat1 DoS) - will_not_fix in Debian bookworm; no attacker-controlled XML path reaches expat in this container.
  • CVE-2026-40356 (krb5 GSS-API DoS) - no patched Debian package available; Kerberos is not used by codeflare.

Additional Go-stdlib CVEs in rclone/lazygit and libexpat in transitive deps suppressed with the same rationale.

Full Changelog: v1.1.7...v1.1.8