Skip to content

build(deps): bump softprops/action-gh-release from 2 to 3 - #2

Merged
mlcyclops merged 1 commit into
masterfrom
dependabot/github_actions/softprops/action-gh-release-3
Jun 20, 2026
Merged

mlcyclops merged 1 commit into
masterfrom
dependabot/github_actions/softprops/action-gh-release-3

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jun 20, 2026

Copy link
Copy Markdown
Contributor

Bumps softprops/action-gh-release from 2 to 3.

Release notes

Sourced from softprops/action-gh-release's releases.

v3.0.0

3.0.0 is a major release that moves the action runtime from Node 20 to Node 24. Use v3 on GitHub-hosted runners and self-hosted fleets that already support the Node 24 Actions runtime. If you still need the last Node 20-compatible line, stay on v2.6.2.

What's Changed

Other Changes 🔄

  • Move the action runtime and bundle target to Node 24
  • Update @types/node to the Node 24 line and allow future Dependabot updates
  • Keep the floating major tag on v3; v2 remains pinned to the latest 2.x release

v2.6.2

What's Changed

Other Changes 🔄

Full Changelog: softprops/action-gh-release@v2...v2.6.2

v2.6.1

2.6.1 is a patch release focused on restoring linked discussion thread creation when discussion_category_name is set. It fixes [#764](https://github.com/softprops/action-gh-release/issues/764), where the draft-first publish flow stopped carrying the discussion category through the final publish step.

If you still hit an issue after upgrading, please open a report with the bug template and include a minimal repro or sanitized workflow snippet where possible.

What's Changed

Bug fixes 🐛

v2.6.0

2.6.0 is a minor release centered on previous_tag support for generate_release_notes, which lets workflows pin GitHub's comparison base explicitly instead of relying on the default range. It also includes the recent concurrent asset upload recovery fix, a working_directory docs sync, a checked-bundle freshness guard for maintainers, and clearer immutable-prerelease guidance where GitHub platform behavior imposes constraints on how prerelease asset uploads can be published.

If you still hit an issue after upgrading, please open a report with the bug template and include a minimal repro or sanitized workflow snippet where possible.

What's Changed

... (truncated)

Changelog

Sourced from softprops/action-gh-release's changelog.

0.1.13

  • fix issue with multiple runs concatenating release bodies #145
Commits
  • 718ea10 release 3.0.1
  • f1a938b chore(deps): bump esbuild from 0.28.0 to 0.28.1 (#802)
  • 0066ead chore(deps): bump vite from 8.0.14 to 8.0.16 (#806)
  • dc643ca chore(deps): bump the npm group with 3 updates (#805)
  • 85ee99b chore(deps): bump actions/checkout in the github-actions group (#804)
  • 9ed3cf9 chore(deps): bump the npm group with 2 updates (#800)
  • 3efcac8 chore(deps): bump the npm group with 3 updates (#798)
  • 05d6b91 chore(deps): bump brace-expansion from 5.0.5 to 5.0.6 (#797)
  • 403a524 chore(deps): bump @​types/node from 24.12.2 to 24.12.3 in the npm group (#796)
  • 437e073 chore(deps): bump the npm group with 4 updates (#792)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [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@v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

dependabot Bot commented on behalf of github Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Labels

The following labels could not be found: ci, dependencies. Please create them before Dependabot can add them to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

@mlcyclops
mlcyclops merged commit 822d2de into master Jun 20, 2026
5 checks passed
@dependabot
dependabot Bot deleted the dependabot/github_actions/softprops/action-gh-release-3 branch June 20, 2026 03:35
mlcyclops added a commit that referenced this pull request Jun 20, 2026
…9.6 + P9.7)

Two connected gaps in the personalization knowledge graph, per user report.

P9.6 — the graph showed no relational lines. Root cause: neither distiller
extractor emitted relations, so the store's links array stayed empty and the
(correct) renderer had nothing to draw.
- modelExtractor now requests + parses a relations[{to,relation}] array (real
  semantic edges); the offline heuristic chains same-turn non-link facts with a
  weak 'mentioned with' co-occurrence edge; distillTurn resolves a relation's
  target to the real turn-entity (its own kind) and dedups undirected.

P9.7 — no way to seed the graph. Import a ChatGPT or Claude data export through
the SAME fail-closed gated distiller the live chat uses: every imported USER
message is scanned before any fact is stored (keystone #2 on the import path);
a poisoned old transcript quarantines exactly like a live message. Assistant
text never teaches. Imported facts carry source_session_id=import:<vendor>.
- harness/personal/import_adapters.ts: detectVendor + parseExport normalize both
  ChatGPT (mapping/author.role/content.parts) and Claude (chat_messages/sender).
- harness/personal/importer.ts: gated import, deferred single save (new distillTurn
  persist:false avoids O(n^2) re-encryption), emits personal_facts_imported.
- contracts.ts: + EventName personal_facts_imported (only frozen-contract change).
- desktop: importChatExport() (active-compartment routing; cui fail-closed if locked),
  POST /api/personal/import, 'Import history' button reusing the in-app folder browser.

+11 tests (vendor detection, both formats, clean import, poisoned-message resilience,
edges, provenance). 363 harness pass. root+desktop tsc clean, renderer bundles,
endpoint verified live in preview. ADR-0017 records the design.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jun 20, 2026
…moglyphs + source-scoped gate (ADR-0019 A+B) (#26)

A user generating an image of a physics answer hit repeated false-positive
quarantines on the model's own generate_image content (Δv, Σ, 5μm).

A) scanner (keystone #1): mixed-script-homoglyph now flags ONLY genuine Latin
   look-alike Greek/Cyrillic codepoints (_LATIN_CONFUSABLE), not the whole
   Greek/Cyrillic block. Non-confusable math (Δ Σ Π Λ Φ λ μ π θ) mixed with Latin
   passes clean; real spoofs (Cyrillic 'а' in pаypаl, Greek omicron in lοgin)
   still fire. New clean-corpus fixtures assert the physics case = zero findings;
   adversarial fixtures stay green.

B) gate (invariant #3): new optional GatePolicy.nonBlockingTypes demotes given
   finding types to recorded-but-not-blocked (kept in findings, labeled suspicious
   so keystone #2 still blocks promotion). The omp gate scans the model's OWN tool
   args with TOOL_POLICY demoting mixed-script-homoglyph — a homoglyph-only hit in
   model-authored content no longer dead-ends the task. Dangerous vectors
   (zero-width, bidi, tag-block, PUA) still hard-block; a dangerous finding
   alongside a demoted one still blocks; external/imported text stays strict;
   fail-closed law untouched (gate.failclosed.test green).

+1 gate test. harness 369 pass, scanner pytest green. ADR-0019 records A+B and
plans C (block observability + review + approve/override) as the next increment.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jun 23, 2026
#51) (#56)

rememberActivity promoted a semantic fact for every allowed tool call
(entity omp:<tool>), filling semantic_facts with mechanical activity
(omp:bash/read/find/web_search/job/yield) that #50 then had to filter out of
recall. Raw tool I/O is provenance, not durable knowledge. Keep ingestArtifact
(scan + trust-label + raw, for the security/audit trail) and drop the fact
promotion. Genuine learning still flows through the personalization graph
(learnFromTurn), and a subagent's SUMMARIZED result still promotes through the
keystone-#2 gate (runs/task_gate.ts gateSubagentResult) — that path is
unchanged and its tests still assert clean-promotes / poisoned-blocked.

Pairs with #50 (read-side exclusion): now the noise is neither generated nor
recalled. task_gate (6) + memory (91) + quarantine gate (6) tests pass; demo09
(keystone #2) and demo17 (recall) pass; tsc clean.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jun 24, 2026
…l hygiene) (#70)

ADR-0042: records the opt-in personalAiExtract toggle (default OFF) — model-based
extraction for richer semantic facts + cross-turn relations at one model call/turn,
reusing backend.complete(); offline heuristic + cross-turn linker remain the free
baseline (PR #66, ADR-0010).

ADR-0043: records the recall-hygiene decision — recall excludes mechanical tool
activity (omp:*/subagent:*, PR #50) and rememberActivity stops promoting raw tool
I/O as durable facts while keeping provenance ingest (PR #56); subagent-result
promotion through the keystone-#2 gate is untouched (ADR-0009, keystone #2).

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jun 26, 2026
…d the podcast seam (ADR-0071) (#101)

Fills the ADR-0070 PodcastBackend seam with its first concrete backend.
OpenAiCompatibleTtsBackend POSTs each podcast turn to {baseUrl}/v1/audio/speech
(a self-hosted Kokoro server, or any OpenAI-compatible TTS) with a per-speaker
voice and concatenates the returned WAV segments into one briefing.

Chosen first because it is the verified air-gap path (no cloud account, no
allowlist) and adds NO Python (a TS HTTP client, invariant #2) — unlike
ElevenLabs (access-gated) and NotebookLM Enterprise (GCP), which implement the
same interface later.

Pure, chunk-aware parseWav/buildWav/concatWav + an injectable fetch transport =
fully tested offline (9 tests). Fail-safe: any synth error (down endpoint,
non-200) degrades to a script-only result, never throws. PodcastResult gained an
additive audio?: Uint8Array. demo-P-BRIEF.2 runs repo-logs → script → synth →
one WAV via a mock by default (air-gap/CI) and live with LUCID_TTS_BASE_URL.

harness 537 pass / 1 skip / 0 fail; typecheck clean.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jun 26, 2026
…transcription seam (ADR-0073) (#103)

The symmetric mirror of the P-BRIEF.2 TTS backend — voice IN. A
TranscriptionBackend seam + a first OpenAiCompatibleSttBackend that POSTs mic
audio as multipart to {baseUrl}/v1/audio/transcriptions (a self-hosted Whisper
server, or any OpenAI-compatible endpoint).

Chosen first for the same reasons as the Kokoro TTS adapter: air-gap default
(local Whisper — audio never leaves the host), no new Python (a TS HTTP client,
invariant #2), and no new trust surface (the transcript is ordinary user input
through the existing scanned path).

Testable + fail-safe: injectable fetch transport; empty audio short-circuits with
no network call; any error (down endpoint, non-200, missing text) returns an
EMPTY transcript with a note, never throws — a broken STT endpoint never crashes
the composer. 5 tests; demo-P-STT.1 runs audio → transcript via a mock by default
(offline/CI) and live with LUCID_STT_BASE_URL.

The mic UI (chat + goal composer) is P-STT.2, with two guardrails recorded in the
ADR: local-only STT under managed lockdown (audio sovereignty); no voice-confirm
of a catastrophic exec-approval.

harness 542 pass / 1 skip / 0 fail; typecheck clean.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jun 29, 2026
… self-heal (v1.8.11) (#164)

P-NETDIAG.1 (ADR-0090): a developer-mode Network diagnostics panel in the Logs
view, fed by an always-on backend watcher (desktop/netdiag.ts). Captures loopback
connections, EVERY listener incl. all-interface 0.0.0.0/[::] binds, an active TCP
probe of the OAuth callback port (:1455), the Windows DNS cache, and a rolling
event log; a new listener on a watched/loopback port is flagged a callback
candidate. Pure netstat/lsof/tasklist parse + diff helpers (unit-tested);
read-only OS shell-outs, never binds or mutates. Standalone CLI sibling
tools/netwatch.ts.

P-NETDIAG.1b (ADR-0091): the root-cause fix the watcher surfaced. omp's
auth-broker login writes a fresh token but leaves a stale disabled_cause from a
prior logout, so a valid login stays ignored and the UI can never recover.
desktop/auth_vault.ts clearDisabledCredential() nulls ONLY that flag (token blob
untouched, read-before-write, busy_timeout, best-effort), wired into dev.ts's
OAuth success path so connect self-heals before the omp respawn. One-shot repair
CLI tools/omp_auth_reenable.ts.

Cosmetic/diagnostic only: invariant #3 fail-closed untouched (no gate input, no
allow/block verdict), #2 language boundary (TS only, no new .py), #1 extend-omp
(no fork). 17 new tests + make demo-P-NETDIAG.1; desktop 735/0, harness 544/0,
typecheck + license-headers clean. Bump v1.8.10 -> v1.8.11.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops pushed a commit that referenced this pull request Jun 30, 2026
…blish seam (0102)

Design-only round (SCOPE/PLAN ADRs; no production code), per the chosen
design-only + sequenced-one-branch execution model.

- ADR-0099/0100 (P-KB.1-2): an OpenKB-style "compiled KB" — a TS+DuckDB (no
  Python) sibling to the vector RAG spine. New kb_graph.duckdb (migrations
  0011+) of documents + summary/concept/entity pages + cross-link wikilinks +
  citations + changelog, compiled by the most-used model and scanned
  fail-closed on the source AND every derived page (keystone #2). A retrieval
  router answers from vector / compiled / both; the page graph reuses the
  existing graph renderer.
- ADR-0101 (P-SKILL.5): Skill Studio — a button that analyzes the day's/week's
  work (sessions, AI-LOC, loop run-log, usage ledger) and drafts Agent Skills
  via the most-used model, each scanned through the importSkill gate and
  reviewed before being codified into the Local Skills Registry. Concretizes
  the deferred P-SKILL.2/.3.
- ADR-0102 (P-SKILLREG.2): a RegistryPublisher seam (mirrors the SIEM Sink) —
  public ships the interface + a default local publisher; remote publishers
  (cloud OCI registries + custom git: GitLab/GitHub/Azure DevOps) are private
  add-on IP (ADR-A014/A015, staged separately), egress-gated.

README: compiled-KB block, Skill Studio + remote-publish blocks, 4 roadmap
rows; ADR count 98 -> 102. PROGRESS: shipped/stubbed/next. New contracts.ts
EventName values named but deferred to their own frozen-contract increment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SUnSuScrGPJDExyp2oCA2b
mlcyclops added a commit that referenced this pull request Jul 5, 2026
… Studio & publish seam (0099–0102) (#154)

* docs(adr): ADR-0088 skill directory/menu + ADR-0089 enterprise skills registry spike

ADR-0088 (P-SKILL.4, SCOPE/PLAN): one Agent Skill directory + management menu
unifying the bundled corpus (ADR-0029), omp-discovered skills, scan-gated import
(ADR-0045), and the curated .agents/skills/ tree under one governed view —
source root, closed-set trust label, enable/disable, inspect, fail-closed
re-scan, and confined remove. Disabled/suspicious/quarantined skills are never
loaded. Defines the `registry` source seam ADR-0089 plugs into.

ADR-0089 (P-SKILLREG.1, SCOPE/PLAN): enterprise skills-registry capability spike.
Cross-provider research of record (mid-2026): AWS Agent Registry / Azure Foundry
Skills / Google Skill Registry exist but are preview, not GA, have no Terraform
resource, and AWS is metadata-only; OCI, IBM Cloud, VMware, Nutanix, NetApp,
KVM have none. Decision: skills-as-OCI-artifacts on an S3-compatible backend
(Cosign + SLSA), self-hosted everywhere via Terraform, first-party registries as
optional metadata sync only, always self-hosted in IL5 (separate aws-us-gov /
usgovcloudapi.net / oraclegovcloud.com OC2/OC3 partitions; GCP Assured Workloads).
Public ships only the read-only registry-reader seam (verify-signature →
scan-gate → install); the runbooks + their ADRs (ADR-A012/A013) are private
add-on IP, staged separately.

README: new "Agent Skills directory & enterprise registry (Coming Soon)" section
+ two roadmap rows; ADR count 87 → 89. PROGRESS: shipped/stubbed/next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SUnSuScrGPJDExyp2oCA2b

* docs(adr): compiled KB sibling (0099/0100) + Skill Studio (0101) + publish seam (0102)

Design-only round (SCOPE/PLAN ADRs; no production code), per the chosen
design-only + sequenced-one-branch execution model.

- ADR-0099/0100 (P-KB.1-2): an OpenKB-style "compiled KB" — a TS+DuckDB (no
  Python) sibling to the vector RAG spine. New kb_graph.duckdb (migrations
  0011+) of documents + summary/concept/entity pages + cross-link wikilinks +
  citations + changelog, compiled by the most-used model and scanned
  fail-closed on the source AND every derived page (keystone #2). A retrieval
  router answers from vector / compiled / both; the page graph reuses the
  existing graph renderer.
- ADR-0101 (P-SKILL.5): Skill Studio — a button that analyzes the day's/week's
  work (sessions, AI-LOC, loop run-log, usage ledger) and drafts Agent Skills
  via the most-used model, each scanned through the importSkill gate and
  reviewed before being codified into the Local Skills Registry. Concretizes
  the deferred P-SKILL.2/.3.
- ADR-0102 (P-SKILLREG.2): a RegistryPublisher seam (mirrors the SIEM Sink) —
  public ships the interface + a default local publisher; remote publishers
  (cloud OCI registries + custom git: GitLab/GitHub/Azure DevOps) are private
  add-on IP (ADR-A014/A015, staged separately), egress-gated.

README: compiled-KB block, Skill Studio + remote-publish blocks, 4 roadmap
rows; ADR count 98 -> 102. PROGRESS: shipped/stubbed/next. New contracts.ts
EventName values named but deferred to their own frozen-contract increment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SUnSuScrGPJDExyp2oCA2b

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
mlcyclops added a commit that referenced this pull request Jul 5, 2026
…ands on macOS (ADR-0168) (#231)

P-SANDBOX.1-.3 made the execution boundary real, mediated, and audited — but
only on Linux (bwrap). macOS was the disclosed passthrough. This closes it:

- harness/runs/sandbox_exec.ts: SeatbeltBackend wraps the omp spawn in
  `sandbox-exec -p <profile>` (isolates:true; available when sandbox-exec is on
  PATH). Pure seatbeltProfile(caps,ctx) — the SAME three network states as
  bwrap: canNetwork:false → (deny network*) + deny mDNSResponder mach-lookup
  (DNS truly cut); canNetwork:true + proxy → egress CONFINED TO LOOPBACK so a
  raw-IP socket ignoring HTTP_PROXY is kernel-DENIED (bwrap only drops it) +
  HTTP(S)_PROXY set; canNetwork:true + no proxy → fail-closed total deny.
- resolveBackend: darwin + sandbox-exec → Seatbelt; else disclosed passthrough
  / managed-fail-closed. Disclosure + require-isolation reasons refreshed.

Splits ADR-0157's ".4 (later)" catch-all (recorded in ADR-0168): macOS Seatbelt
ships here; Windows AppContainer needs native Win32 (CreateProcess +
SECURITY_CAPABILITIES) → its own future increment+ADR (inv #2: no new native
surface smuggled in); Linux slirp4netns raw-socket forwarding → its own
follow-up. Honest residual: macOS mediated profile leaves getaddrinfo→
mDNSResponder reachable (DNS-TXT name lookup can resolve) pending a resolver
interception; the network-off profile has no such residual.

26 sandbox_exec tests (Seatbelt resolution/profiles/loopback-confine/DNS-cut/
argv/require-isolation/downgrade) + demo-P-SANDBOX.4 green; P-SANDBOX.1/.2/.3
demos still green; tsc + license clean.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jul 6, 2026
…tract (ADR-0172) (#234)

Windows was the last platform on the disclosed passthrough (Linux/macOS got real
containment in .1-.5). Unlike bwrap / sandbox-exec, Windows has NO argv-wrapper
for AppContainer — it needs a native CreateProcess with SECURITY_CAPABILITIES +
WFP egress rules, which doesn't fit the seam's wrap→{cmd,args,env} contract. So
we introduce a thin first-party helper `lucid-appcontainer <flags> -- <argv>`
that DOES fit the contract; this increment builds + tests the seam + flag
contract, and the native helper is P-SANDBOX.7.

- harness/runs/sandbox_exec.ts: AppContainerBackend (isolates:true; available()
  = lucid-appcontainer on PATH) + pure appContainerArgs(caps,ctx) — same three
  network states as bwrap/Seatbelt: network-off → --deny-network; mediated →
  --loopback-only (raw-IP sockets WFP-denied) + HTTP(S)_PROXY; no-proxy →
  fail-closed --deny-network; --workspace/--home bind rw. resolveBackend win32 →
  AppContainer when the helper is present, else disclosed / managed-fail-closed.
- Extended the P-SANDBOX.5 panel types (sandbox_status/bridge/sandbox_panel) with
  the "appcontainer" backend + a "Windows AppContainer" label.

Fail-safe: the helper isn't bundled yet, so available() is false on every current
Windows box ⇒ disclosed passthrough — behavior UNCHANGED from .1-.5 until it ships.
Rejected Bun-FFI-direct (breaks the argv-plan contract) + Windows-Sandbox/Job-
Objects (heavyweight / no net isolation); chose the helper (inv #2: no native
surface smuggled in — deferred to its own increment).

33 sandbox_exec tests (resolution with/without helper, require-isolation, flag
states, loopback-confine, argv, available() gating, downgrade) + demo-P-SANDBOX.6
green; P-SANDBOX.1-.5 demos still green; all 3 tsconfigs + license clean.
Built in an isolated git worktree.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jul 6, 2026
…ontainer), verified (ADR-0173)

P-SANDBOX.6 (ADR-0172) built the seam that shells to `lucid-appcontainer
<flags> -- <argv>` and deferred building the helper "because it introduces
the first native-code surface." This is that helper, and it resolves the
native-surface tension WITHOUT a C/Rust/Python tree:

- tools/appcontainer/lucid_appcontainer.ts: a TypeScript helper compiled to a
  standalone lucid-appcontainer.exe via `bun build --compile` (make
  build-appcontainer, --target=bun-windows-x64). It uses bun:ffi for the real
  Win32: derive/create an AppContainer SID, SECURITY_CAPABILITIES with an EMPTY
  capability set (no internetClient ⇒ no outbound network = --deny-network),
  CreateProcessW inside the AppContainer via PROC_THREAD_ATTRIBUTE_SECURITY_
  CAPABILITIES, wait + propagate the child exit code. Win32 via FFI from TS
  keeps invariant #2 intact (no new native/Python source tree).

- Fail-closed (inv #3): bad args → exit 2 (before any spawn); a mode it can't
  enforce (--loopback-only), non-Windows, or any FFI failure → exit 3. A helper
  that can't contain BLOCKS — never a passthrough (false security).

VERIFIED live on Windows 10: a benign child (curl --version) runs inside the
AppContainer (exit 0); a networked child (curl https://example.com) is BLOCKED
(http_code=000, exit 28) while the same curl outside returns 200; the compiled
.exe reproduces the block. 11 pure parser tests + demo-P-SANDBOX.7 (live block on
Windows, fail-closed refusal off-Windows) green.

Deliberately NOT bundled/activated yet: the common trusted-local session is
canNetwork:true → --loopback-only (mediated), which needs an AppContainer
loopback exemption + WFP rules = P-SANDBOX.7b. Activating deny-network-only
would refuse the common session. Windows stays disclosed passthrough until .7b.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jul 6, 2026
…ontainer), verified (ADR-0173) (#236)

P-SANDBOX.6 (ADR-0172) built the seam that shells to `lucid-appcontainer
<flags> -- <argv>` and deferred building the helper "because it introduces
the first native-code surface." This is that helper, and it resolves the
native-surface tension WITHOUT a C/Rust/Python tree:

- tools/appcontainer/lucid_appcontainer.ts: a TypeScript helper compiled to a
  standalone lucid-appcontainer.exe via `bun build --compile` (make
  build-appcontainer, --target=bun-windows-x64). It uses bun:ffi for the real
  Win32: derive/create an AppContainer SID, SECURITY_CAPABILITIES with an EMPTY
  capability set (no internetClient ⇒ no outbound network = --deny-network),
  CreateProcessW inside the AppContainer via PROC_THREAD_ATTRIBUTE_SECURITY_
  CAPABILITIES, wait + propagate the child exit code. Win32 via FFI from TS
  keeps invariant #2 intact (no new native/Python source tree).

- Fail-closed (inv #3): bad args → exit 2 (before any spawn); a mode it can't
  enforce (--loopback-only), non-Windows, or any FFI failure → exit 3. A helper
  that can't contain BLOCKS — never a passthrough (false security).

VERIFIED live on Windows 10: a benign child (curl --version) runs inside the
AppContainer (exit 0); a networked child (curl https://example.com) is BLOCKED
(http_code=000, exit 28) while the same curl outside returns 200; the compiled
.exe reproduces the block. 11 pure parser tests + demo-P-SANDBOX.7 (live block on
Windows, fail-closed refusal off-Windows) green.

Deliberately NOT bundled/activated yet: the common trusted-local session is
canNetwork:true → --loopback-only (mediated), which needs an AppContainer
loopback exemption + WFP rules = P-SANDBOX.7b. Activating deny-network-only
would refuse the common session. Windows stays disclosed passthrough until .7b.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jul 6, 2026
…ILL.4/.5, P-SKILLREG.1/.2, P-KB.1/.2/.2b) (#242)

* Build the skills governance suite + the compiled knowledge base

Seven verified increments across two epics, each fail-closed + scan-gated.

Skills governance:
- P-SKILL.4 (ADR-0097): the Agent Skill directory + per-skill management
  (inspect / re-scan / remove), closed-set trust labels, enable/disable.
- P-SKILLREG.1 (ADR-0098): the enterprise registry READER seam
  (Ed25519 verify -> fail-closed scan-gate -> confined install).
- P-SKILL.5 (ADR-0101): Skill Studio (analyze recent work -> model-drafted
  candidates -> gated codify).
- P-SKILLREG.2 (ADR-0102): the publish seam (RegistryPublisher +
  LocalRegistryPublisher + fail-safe PublishDispatcher).

Compiled knowledge base:
- P-KB.1 (ADR-0099): the compiled-page store + gated compile pipeline
  (harness/kb, TS+DuckDB, frozen migration 0011).
- P-KB.2 (ADR-0100): the hybrid retrieval router (vector | compiled | both)
  + kept-in-sync + contradiction flag.
- P-KB.2b: the desktop surface (kbStore + /api/kb routes + a Compiled-KB
  graph view reusing mountGraph in the Knowledge panel).

Invariants held: fail-closed everywhere (dead scanner => quarantine),
keystone #2 (derived/registry content never auto-trusted), delimited
untrusted data (#5), closed trust set (#7), frozen DuckDB migration (#10),
no contracts.ts change (EventNames deferred, inv #8), no Python outside
scanner-sidecar (#2).

Verified: root tsc green; bun test desktop + harness green (modulo the
documented fs_browse / lucid_acp Windows path-sep fails); renderer bundles;
demo-P-SKILL.4/.5, demo-P-SKILLREG.1/.2, demo-P-KB.1/.2/.2b all pass;
BUSL-1.1 headers present.

* Potential fix for pull request finding 'CodeQL / Incomplete string escaping or encoding'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
mlcyclops added a commit that referenced this pull request Jul 9, 2026
Package the same relay the desktop embeds as a headless, self-hostable rendezvous
so a different person can actually reach a shared session - on your own box, an
office server, or a DGX Spark / Ubuntu 24 jumpbox. It's the coordination point
BOTH transports need (the relay path, and the WebRTC signaling handshake).

- tools/relay/serve.ts: a CLI entrypoint (env / --flag config: HOST/PORT,
  TLS_CERT/TLS_KEY for wss://, MAX_ROOMS/PEERS/FRAME/IDLE), graceful shutdown, a
  status heartbeat. Standalone defaults to 0.0.0.0:8790; the desktop embed still
  defaults to loopback.
- relay_server.ts made SELF-CONTAINED: the 4-byte envelope header ops are inlined,
  so it imports NOTHING (no WebCrypto, no @oh-my-pi/pi-wire) - the deploy is two
  files + Bun, zero npm deps. Added optional `tls` (Bun serves wss:// directly) +
  a /healthz probe (aggregate counts only, never a roomId/key/session bytes).
- tools/relay/Dockerfile (a tiny 2-file image), tools/relay/lucid-relay.service (a
  hardened systemd unit for Ubuntu 24), tools/relay/README.md (local/office/DGX/
  jumpbox; TLS direct or reverse-proxy; firewall; client wiring + the
  collab.allowedRelays governance).

Language stays TypeScript (invariant #2: the only Python here is the scanner). The
relay is a dumb byte forwarder and its logic is already tested in TS, so packaging
it is one language + zero new surface. A FastAPI relay for a Python-first ops shop
is the SAME wire protocol and belongs in the private add-on repo as enterprise
deployment IP; LUCID clients connect to either unchanged.

demo-P-COLLAB.9 spawns `bun run tools/relay/serve.ts` as a SEPARATE process and
drives a real host + guest through it (welcome -> live event -> bye), asserting
/healthz reflects the live room. relay_server.test.ts + tsc + license green.

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jul 14, 2026
…307)

* Add headless KG-pack builder tools/build_kg_pack.ts (ADR-0207)

Runs the exact in-app pack-authoring pipeline from the CLI so the role-pack
product line builds repeatably (`make kg-pack ROLE=bd`, or --all), composing
already-shipped pieces with zero new trust path:

  readKbSources -> createKg -> ingestSourcesIntoKg (fail-closed scan + compile,
  model injected as backend.complete = the same backend the LUCID session uses,
  resolved to the app's most-used model like /api/kb/ingest-batch) ->
  exportKgPack (Ed25519-sign when LUCID_KG_PACK_SIGNING_KEY is set) ->
  importKgPack (verify + re-scan round-trip, proving the pack installs).

Builds into an isolated temp KB workspace (never the user's ~/.omp graphs) and
writes <slug>.lkgpack(.zip) next to its source dataset. A build catalog maps
each role folder under LucidAgentDesigns/KG Packs/ to name/role/desc/licensing +
a stable product id (the five existing storefront ids match). Cost controls:
--limit N, --dry-run (no model calls), --all.

Verified: 10 pure-helper unit tests; --dry-run loads 365 BD conversations; a
live --limit 2 smoke compiled 2 -> 28 pages (0 quarantined/errored) with
claude-fable-5, exported, and verify-import round-tripped OK. Root tsc + license
clean. No signing key committed (smoke pack was unsigned).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Settings clone reaches parity with agent clone; add AskSage GPT-5.6 (ADR-0208/0209)

Settings "Clone a git repo" now clones private repos headlessly like the
agent does. cloneRepo injects a host token (GITHUB_TOKEN/GH_TOKEN/GITLAB_TOKEN,
https only) via a per-command http.extraHeader (never persisted to .git/config,
redacted from errors), sets GIT_TERMINAL_PROMPT=0, trims the trailing-dot repo
name (the Windows folder-desync behind l.e.a.p.s.), clears leftover partial
clones, and surfaces an actionable auth hint instead of a generic toast. Pure
helpers exported + unit-tested (desktop/workspace.test.ts).

AskSage CIV GPT-5.6 added to OPENAI_MODELS + MODEL_CTX so the newly-added gov
model populates the picker; ADR-0209 scopes a live /get-models fetch so future
models appear without a code change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Vault-backed git PAT for private-repo clones (ADR-0210)

The ADR-0208 follow-up: enter a git token once instead of exporting an env var.
Settings -> Workspace stores a PAT in the OS-encrypted vault (ref git_pat, via
credStore) with a saved indicator + Remove. main.ts prepareGitToken injects it
as LUCID_GIT_PAT into the dev child at spawn (the Figma/Local-Providers vault->env
pattern); hostTokenForUrl uses it as the host-agnostic fallback after a workflow's
own GITHUB_TOKEN. A token saved this session works immediately with no relaunch:
the clone request carries an optional inline pat (sessionGitPat) and
resolveCloneToken prefers it over env. Stays leak-safe (http.extraHeader, redacted,
never sent to the agent).

resolveCloneToken + the LUCID_GIT_PAT fallback are unit-tested (17 workspace tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Enforce AskSage lockdown server-side, fail-closed (ADR-0211)

AskSage-only "lockdown" was enforced only in the renderer (one-shot model switch
on the toggle click + picker hiding), so it silently failed on a fresh launch with
lockdown persisted ON and after every omp respawn (workspace change, clone, Refresh
models, provider-key change): the maker turn used omp's default direct model.

Add enforceAsksageLock() in acp_backend.ts - a fail-closed clamp in prompt() that
forces the active model to an asksage-routed one before every send and REFUSES the
turn ([blocked: ...]) when lockdown is on but no gov model exists (never routes
direct), plus a best-effort clamp on fresh session init so the picker/status show
gov immediately. Fix the checker's broken /gov/i predicate (real ids like
asksage-openai/gpt-5.6 have no "gov" substring, so it matched nothing and fell
through to all models) -> shared isAsksageRouted = /asksage/i. Renderer guard:
lockdown can't be enabled without a configured AskSage key.

resolveLockdownModel + isAsksageRouted are pure + unit-tested, including the
fail-closed "no gov model -> block" case (15 checker_model tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Lockdown covers egress + agent runs; RAG on GPT-5.6 Luna; real 5.6 ids (ADR-0212)

Completes the ADR-0211 lockdown work and extends the sovereignty boundary:

- Egress under lockdown is now fail-closed: the in-process gate blocks ALL public
  egress (web_search / browser / web / fetch / navigate / external http(s)) with an
  audited high-severity event, so CUI can't backflow to a public service. Local
  file:// previews stay allowed. omp owns web_search and takes no endpoint, so the
  control is deny, with the AskSage RAG /query model as the sanctioned alternative.
- Built-agent runs honor lockdown via a shared Backend.resolveAgentRunModel() -
  clamps to a gov model or REFUSES (never the default direct "haiku"), wired into
  both the scheduled-automation path and the Builder "Run" route.
- Corrected the GPT-5.6 ids against the LIVE gateway: family is gpt-5.6-luna(mid)/
  -sol/-terra; the earlier bare gpt-5.6 was invalid and is removed. RAG /query
  default moved gpt-5.2 -> gpt-5.6-luna (validated live). Marked recheck-each-release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Per-session CUI/Search mode, violet CUI banner, DoD consent, titlebar Datasets picker (ADR-0213)

Refines ADR-0212's global lockdown egress block into a per-session control and
adds the gov compliance UI:

- Per-session CUI vs Search mode: new sessionModes store (settings_store, fail-
  closed default "cui", bounded) + /api/session-mode route (defaults to the active
  omp session) + bridge. The egress gate now blocks only when
  asksageLocked() && sessionMode(active)==="cui" — a CUI session blocks all public
  egress; a Search session (no CUI datasets) may search while still gov-routed.
- Titlebar CUI/Search toggle + violet CUI banner (lockdown-only, per current
  session, reloaded on session switch; new sessions default CUI). Switching to
  Search routes through a spillage warning that steers CUI work to a separate
  Search session.
- DoD/STIG Notice & Consent banner (standard USG/DoD text in one editable
  constant), once per launch when the gov gateway is configured.
- Restored the AskSage Datasets picker to the titlebar next to Skills: short name
  shown, full name on premium hover, multi-select, count on the chip.

5 new session_mode tests incl. the fail-closed default; tsc + license clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* knowledge_search: RAG grounding for non-AskSage users (ADR-0214, increment 1)

Lets ANY model (Claude/GPT/local) ground on the user's own knowledge, not just
AskSage users. The whole local KB stack (Obsidian/folder/chat ingest, compile,
lexical+graph retrieval, KG registry) already existed and was desktop-wired - it
was just never exposed to the agent. This adds the missing wire:

- harness/omp/knowledge_extension.ts: a read-only knowledge_search tool (mirrors
  codegraph_extension) that POSTs the query to the EXISTING /api/kb/retrieve via a
  token'd LUCID_KB_RETRIEVE_URL (preview-tool env-URL pattern) and returns the
  delimited, cited UNTRUSTED hits; empty -> "add an Obsidian vault/folder" guidance.
- dev.ts sets the URL + adds /api/kb/retrieve to the ?t= token allowlist (additive;
  renderer header call unchanged); acp_backend registers the -e extension in ompArgv
  (always-on, not gated behind AskSage).
- Titlebar Datasets chip dual-purposed: non-AskSage -> "Knowledge" menu (add vault/
  folder via the existing importKgFlow + open the Knowledge panel).

Retrieved text stays delimited/late/untrusted (#5/#6); tool mints no trust (PURE
READ, keystone #2); approval "read" keeps it out of the exec gate. 9 unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Bring-your-own-embeddings ApiEmbedder (ADR-0215, increment 2 part 1)

The "bring your own embeddings" primitive behind the existing Embedder seam:
POSTs {model, input} to an OpenAI-compatible /embeddings endpoint (the user's
OpenAI/Azure key, or a local Ollama/vLLM via Local Providers), so semantic RAG
needs no bundled WASM weights. Pure (fetchImpl-injected), holds no secret at rest,
fail-loud on any non-2xx / count / dim / non-finite so a broken endpoint can't
poison cosine retrieval. Dormant until wired (ingest->embed, retrieve->hybrid,
Settings card) - pending a config decision + an embeddings-capable endpoint to
verify against.

9 unit tests; tsc + license clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Semantic RAG wired: bring-your-own-embeddings end-to-end (ADR-0215 part 2)

Completes non-AskSage semantic search on top of ADR-0214's lexical knowledge_search:

- embed_config.ts: resolves the stored config + vault secret -> an ApiEmbedder
  (fail-safe null keeps retrieval lexical).
- settings_store `embeddings` config + a dedicated "Semantic search" Settings card
  (local Ollama for air-gap, or OpenAI/Azure). Key vaulted (credStore) and injected
  as LUCID_EMBEDDINGS_KEY by main (the Figma/git-PAT vault->env pattern).
- kb_store: per-KG vector store (sibling _vec.duckdb) + vectorDatasetFor (model+dim
  scoped so vector spaces never mix).
- /api/kb/ingest-batch also embeds each source into the KG's vector store (scan-gated
  ingestText, best-effort, never fails the compile job); /api/kb/retrieve auto-upgrades
  to hybrid when an embedder + embedded chunks exist -> knowledge_search transparently
  gains semantic recall, else stays lexical. No WASM bundling.

15 tests (ApiEmbedder w/ injected fetch, config resolver, and the vector-store glue
against real DuckDB incl. a store->retrieve round-trip). Live path needs a real
/embeddings endpoint configured (this profile has none). tsc + license clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Semantic search: Test-endpoint + Re-index actions (ADR-0215 finishers)

- Test endpoint: probeEmbeddings + /api/embeddings/test do a one-vector probe
  against the ENTERED values (incl. an inline key, so it works before save/relaunch)
  and DISCOVER the model's dimension; the card button auto-fills Dim so a mismatch
  can't silently break retrieval.
- Re-index: /api/embeddings/reindex rebuilds every KG's semantic index from its
  compiled PAGES via a shared, idempotent syncVectorIndex (clear-then-embed), so a
  KG compiled before semantic search was enabled can be indexed without re-ingesting.
  Ingest now uses the SAME routine (embeds compiled pages), keeping the two consistent;
  added KnowledgeStore.clearChunks for idempotency.

+2 probe tests (14 green across api_embedder + the DuckDB vector-store glue); tsc +
license clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Shared-session viewer: show thinking + tools, use the whole window (ADR-0216)

Two fixes to the P-COLLAB guest "Watching" panel:

- The viewer now sees the host's THINKING (collapsible block) + TOOL calls
  (name + path chips) + subagent delegations + blocks, not just the final answer.
  The guest handler used to drop those; the frame protocol already relays the full
  ChatEvent stream, so this is a pure render change (no protocol bump).
- When watching, the modal fills the window (calc(100vw/vh - 56px), ~28px border),
  drops the 520px cap, hides the redundant icon/title/desc (the join-head labels
  the session), and cuts padding (22px -> ~12px, transcript 340px -> flex:1) to
  maximize real estate. The connect step stays the small centered modal; X / Leave
  / Escape still close.

tsc clean; renderer-only, additive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Renumber this arc's ADRs 0208-0216 -> 0214-0222 (master assigned 0208-0213 to other decisions)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
mlcyclops added a commit that referenced this pull request Jul 15, 2026
…311)

* Rename to "Lucid Agent" + air-gap-capable installer (ADR-0225)

Display name LucidAgentIDE -> "Lucid Agent" (productName, nsis
shortcut, artifactNames, window/document title). appId is
UNCHANGED so auto-update + userData/chat-history survive.

Close the two first-run network dependencies that broke air-gap
(add-on ADR-A009 diagnosis):

- Vendor omp: re-include node_modules/.bin/omp* in the bundle and
  resolve the shim first in runtime.ts findOmp() (relative path to
  the already-shipped @oh-my-pi/pi-coding-agent, needs only bundled
  bun) -> no `bun add -g` at first launch.
- Bundle a relocatable CPython 3.12.13 (python-build-standalone,
  install_only) per platform via fetch-runtimes.ts, SHA-256 pinned
  and fail-closed (cross-checked vs the release SHA256SUMS).
  runtime.ts bundledPython() resolves it first so `uv venv` never
  runs offline. Scanner has zero pip deps, so a bare interpreter
  suffices. license_headers.ts excludes the vendored runtimes/ tree.

Verified live on Windows: fetch SHA-verifies + extracts CPython
(fixed a GNU-tar C:\-as-host path quirk); the scanner runs offline
under the bundled interpreter (clean text -> [], dirty -> flags
U+200B + U+0430); the bundled omp shim launches omp/16.1.20;
desktop typecheck + license check green.

Remaining gate: a packaged electron-builder offline smoke test per
OS (esp. POSIX .bin/omp symlink handling) before cutting an air-gap
installer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* CI: air-gap smoke gate in the desktop build (ADR-0225)

After electron-builder packages each OS installer, run
desktop/build/airgap-smoke.ts on the same native runner against the
*-unpacked output. It proves the bundle is self-contained: the omp
shim and the scanner's bundled CPython resolve and RUN from
resources/ with no `bun add -g` / `uv venv` / network. Fails the
build (before artifacts upload) if a runtime is missing or lost its
exec bit through packaging.

This is the CI half of the offline verification ADR-0225 flagged as
the remaining gate — in particular it exercises the POSIX .bin/omp
symlink shim + the bundled Python exec bit on the Linux/mac runners,
which can't be checked from a Windows dev box. The scanner probe
doubles as keystone #2 coverage (clean -> no findings; a
homoglyph/zero-width sample -> the expected findings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* v1.11.5: 'Lucid Agent' rename + air-gap-capable installer (ADR-0225)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: mlcyclops <mlcyclops@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.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.

1 participant