Watch
1
0
Fork
You've already forked souveraine
0
Commit graph souveraine/surfaces/quickshell
Author SHA1 Message Date
souveraine
ec87e6a9dc shell: offer resume instead of forcing it 2026-08-13 08:21:39 -04:00
Fimeg
b37b1d396a crash reporter: expected absence is silent, a real read failure is not 2026-08-13 06:54:23 -04:00
Fimeg
e595ef6d72 subconscious panel: colLayer1Active, not the key that does not exist 2026-08-13 06:50:01 -04:00
Fimeg
525157250a shell: context pill tooltip states the real tiers, not the archivist
The tooltip claimed 'Archivist begins compacting around 70%'. The
archivist does not compact. It reads journal/ and writes
system/synthesized/ - a different substrate from the conversation
entirely (core/archivist/mod.rs:5).

The real advisory tiers are 80/90/95 in ConsciousnessEngine::
on_response, and they never force compaction. Icon thresholds moved
from 85/70 to 90/80 to match.
2026-08-12 20:30:34 -04:00
Fimeg
57e53adac3 patches: retire the queue discipline; the shell was never in the agent's cgroup 2026-08-12 20:12:12 -04:00
Fimeg
6f12fceea9 shell: apply 0007, 0010, 0011 — context occupancy, halt register, /new
0007 was fixing a live error: the server has carried named ContextPressure
fields since r463, so event.tokens was undefined and the pill assignment
failed on every turn. Applied and verified against the running shell.

0010 renders a halt in her own register rather than the tool's name.
0011 renames the reset command to /new, which is what clearMessages() does.
2026-08-12 19:50:32 -04:00
Fimeg
0733bfaff7 patches: queue 0011 — the reset command is /new 2026-08-12 19:37:38 -04:00
Fimeg
e50ddee567 patches: queue 0010 — halt rendered in her own register 2026-08-12 18:55:20 -04:00
Fimeg
b9f404cbaf patches: 0007 unblocked — the running server carries f266136 2026-08-12 17:39:19 -04:00
Fimeg
b56635e0f2 patches: 0008/0009 landed; queue is 0001, 0006, 0007
Verified against a running shell rather than a clean load, which immediately
found two faults every prior gate had called clean. Both controls dropped from
0008 recorded as decisions so a later session does not restore them.
2026-08-12 14:54:35 -04:00
Fimeg
44acb11ab5 shell: two faults the load found that no gate did
Both were live in the running shell and invisible to every check that ran
before it. Found by reading the shell's log after Casey applied.

ThinkingCard: missing `import qs.modules.common.functions`

  ReferenceError: ColorUtils is not defined, on every render of every
  reasoning segment. My own defect, shipped through a lint that said clean.

  The lint was blind because I staged an approximation of the composed tree by
  hand instead of linting the composed tree itself. Against the real composed
  tree qmllint reports it plainly: 1 ColorUtils diagnostic before, 0 after.
  Lint the composed tree. A hand-built stand-in tests the stand-in.

Config: sidebar.ai.fontSize restored

  MessageTextBlock (vendor) reads Config.options.sidebar.ai.fontSize and got
  undefined, assigning undefined to font.pixelSize on every text render.
  Pre-existing, not from 0008 — the vendor delegate used MessageTextBlock too.

  Cause is structural: modules/common/Config.qml SHADOWS ii-base's Config
  wholesale, so every key ii-base adds after the fork silently disappears. The
  key even carries an ii-base comment explaining it was added deliberately as
  a live theme binding. Nothing failed; a number was just quietly absent.

  Restored as a live binding, never a literal and never null
  (null-in-a-serialized-config, 2026-08-11).

Verified: shell alive 12s after the Config edit (the crash-loop window),
config.json 46 keys and zero nulls, both fault lines gone from the log.
2026-08-12 14:51:09 -04:00
Fimeg
93fe30a8e7 shell: land the owned message delegate and the speech fixes
Applied 0009 then 0008 (0008's re-synthesize control calls a function 0009
adds). Casey applied and reloaded; verified against a running shell rather
than from a clean load.

0009 Speech.qml
  stop() could not stop. playProc ran `sh -c "mpv ... || ffplay ..."` — a
  compound command, so sh does not exec-replace itself and SIGTERM killed the
  wrapper while the player kept sounding as an orphan. Reproduced directly.
  That is the back-to-back TTS slam: every stop left audio playing and the
  next speak started a second player over it. Shell dropped; the pid held is
  now the pid making noise. ffplay fallback deleted rather than repaired —
  needing a fallback is what forced the wrapper that broke the kill.
  resynthesize() added, bypassing the cache: the button existed for "that came
  out wrong" and, being keyed on the same text, always replayed the identical
  file. synthesizing/playing split out of one `speaking` boolean.

0008 AiChat.qml
  One line: delegate AiMessage -> AgentMessage. The vendor block named 8 tools;
  the registry holds 19. The 11 it could not see were exactly the interiority
  surface — outfit, nickname, subagent, atmosphere, reach, consult, itinerary,
  todo, schedule, halt, intrusive.

  regenerate and edit dropped deliberately, per Casey: text regeneration is not
  possible (Ai.regenerate() already returned advice) and there is no in-place
  edit (the vendor wrote to a local array the server never sees). delete is
  armed and states that it hides locally only. Do not restore them.

Queue entries removed here, per the directory's own discipline.
2026-08-12 14:50:57 -04:00
Fimeg
cb3785bcbd patches: correct the queue; retire 0002 as obsolete, clear landed 0003/0004
The queue section claimed 0001-0004 were all unapplied. Verified with
git apply --check in both directions: 0003 landed as 8c434df, 0004 as
23cebc5, and 0002 can no longer apply at all.

0002 patched inThinkBlock in services/Ai.qml. That variable no longer
exists - typed segments made the think-fence collision impossible by
construction rather than by escaping harder. Retired, not abandoned.

0001 and 0006 were on disk and undescribed. Both now carry their
reasoning here. 0007's block records the specific installed version it
waits on, since 'needs the server first' is not actionable a month
later.

A queue is not an archive; git keeps history.
2026-08-12 14:12:26 -04:00
Fimeg
ba13d56afc patches: queue 0009 speech stop/resynthesize; unblock 0008
0008 was blocked because the owned delegate carried none of the vendor's
seven message controls. df11bba carries five and drops two deliberately;
the header now records which and why rather than only lifting the warning.

0009 depends on nothing but is a prerequisite for 0008's re-synthesize
control doing anything real.
2026-08-12 13:55:35 -04:00
Fimeg
df11bbab96 shell: carry the message control row into the owned delegate
Vendor AiMessage exposed seven controls; the owned delegate had none, which
made patch 0008 a parity regression rather than a swap. Five are carried, two
are deliberately dropped:

  regenerate — the conversation is forward-only and Ai.regenerate() is already
    a no-op returning advice. A button whose only behaviour is to explain that
    it does nothing is worse than no button.
  edit — there is no in-place edit. The vendor's wrote to a local array the
    server never sees, so the message read back was not the message held.

delete is kept but armed: removeMessage() splices two local arrays and leaves
the server transcript untouched, so it is a view filter wearing a delete icon.
The armed row says so in words and replaces the controls in place rather than
opening a modal, which on a layer-shell surface would fight for focus.

speak and copy are separated at the source. copy takes the whole content;
speak takes text segments only, so the synthesizer no longer reads reasoning
and tool payloads aloud. Legacy messages without segments fall back to full
content rather than to silence.

re-synthesize prefers Speech.resynthesize() when present and degrades to the
old stop+speak otherwise, because speak() opens with a cache check on the text
and re-synthesis is by definition the same text — the legacy path replays the
identical broken audio.
2026-08-12 13:50:07 -04:00
Fimeg
1951d2b69b shell: document which edits are live and block patch 0008
deploy.sh: name the hazard the composer already implements — a new file
plus a manifest line is inert until the next deploy, while editing a file
already in the manifest is live in the running shell immediately.
Registration is the dangerous act, not creation.

patches/README: 0008 swaps the message delegate to one that does not carry
the vendor control row (regenerate, speak, re-synthesize, copy, edit, raw,
delete). Applying it would remove all seven.
2026-08-12 13:24:34 -04:00
Souveraine
6d0f891d6e shell: own the agent message delegate and the reasoning card
TASK-72 step 2. AgentMessage consumes the typed segment list and dispatches
to owned primitives; ThinkingCard draws reasoning as a segment kind rather
than as <think> punctuation inside a flattened string, which removes the
think-fence collision class by construction.

MessageTextBlock and MessageCodeBlock are deliberately reused from the vendor
snapshot: they are markdown renderers, not agent vocabulary.

Composed by MANIFEST, imported by nothing. The activating edit is queued as
patch 0008. Qt6 qmllint: zero syntax findings; remaining warnings are the
widget-resolution class the vendor AiMessage also produces (38 vs 46).

Not verified: nothing has loaded this. No real tool round has rendered here.
2026-08-12 13:11:19 -04:00
Fimeg
3def2920b8 shell: owned agent surface — tool vocabulary and card
First step of TASK-72's owned destination. modules/souveraine/agent/ is
original Souveraine code; no further agent-surface work lands in ii-base.

ToolVocabulary transcribes src/ui/chat/tool_renderers.rs — the same event
stream, solved once already for the TUI. All 19 registered tools have a kind,
an icon and a summary. The vendor card knew 8: bash read write edit grep glob
list_dir memory. The 11 it could not name are the interiority verbs.

ToolCard groups by what the act is rather than which subsystem serves it, so
acts on the machine and acts on herself read as different families. Status is
legible without opening the payload; collapsed by default except running or
failed.

Composed by the manifest, imported by nothing. Registration is a later step.
2026-08-12 12:55:11 -04:00
Fimeg
5a20307ddd patches: queue 0007, render context occupancy and stop reading hyprctl errors as cursor
Requires f266136 in the running server; without it the pill honestly shows
an em dash rather than a wrong number. Unapplied, unloaded.
2026-08-12 12:20:11 -04:00
Fimeg
e784fe48a3 patches: queue 0006, step-up authenticates through PAM
Authored in a parallel session (Rook, Codex side) on 2026-08-12; committed
here because untracked is the fragile state, not because authorship is mine.
Finding stands on its own: StepUpAuth called souveraine-pam-auth, a binary
never written, and fell back to pkcheck against an action never shipped, so
every grant request was silently denied. Unapplied, unloaded.
2026-08-12 12:20:11 -04:00
Fimeg
d02df0c6bd patches: the queue is 0001-0004, say so 2026-08-12 09:24:06 -04:00
Fimeg
b5671b0b8a patches: retire the stale 0005 entry, record what closed 2026-08-12 09:23:39 -04:00
Fimeg
f7e0e51116 config: never store a null option
Null-valued options serialised into config.json and segfaulted
JsonAdapter on the next launch, killing the shell after load.
Tristate strings (auto/on/off) with boolean fallback.
2026-08-12 09:23:19 -04:00
Fimeg
fb5e9bb80c osk: retire the dead dual-keyboard path 2026-08-11 19:21:21 -04:00
Fimeg
dd19ab227f agent sessions: show conversations, not storage ghosts 2026-08-11 18:47:54 -04:00
Fimeg
12da479c23 bar: finish the shared resource widget 2026-08-11 18:40:35 -04:00
Fimeg
013a06aacf patches: retire the old top-bar agent mount 2026-08-11 18:40:35 -04:00
Fimeg
62638e0e5f osk: recover with Squeekboard, not Stevia 2026-08-11 18:37:57 -04:00
Fimeg
692455c8f0 chat: raise the keyboard when the field is tapped 2026-08-11 18:24:24 -04:00
Fimeg
41d13c9468 dock: yield the bottom edge to the keyboard 2026-08-11 17:21:45 -04:00
Fimeg
7842c04053 turns: never mistake an empty success for Annie 2026-08-11 17:09:42 -04:00
Fimeg
2179b627d1 agent sessions: leave the bar and sit beside chat 2026-08-11 15:43:30 -04:00
Fimeg
3bdc1c8e3c patches: keep island work outside turn fix 2026-08-11 15:01:38 -04:00
Fimeg
3aa7019eb5 turns: survive the surface disappearing 2026-08-11 15:01:18 -04:00
Fimeg
783f09606a island: fix three defects found by actually loading the shell
The island had never been load-tested. All three were fatal or noisy and
none were visible by reading.

StyledToolTip takes `text`, not `content`. Two occurrences, each one a
hard "Cannot assign to non-existent property" that failed the entire
module chain up to shell.qml — the bar would not have come back.

The provider-health tooltip could never have shown even once fixed: a
MaterialSymbol has no `hovered`, and our own StyledToolTip fix treats a
non-hoverable parent as never-show. That block exists specifically so an
unavailable provider is not mistaken for "no sessions", so a tooltip was
the wrong carrier. Stated visibly now.

Island read root.QsWindow.window through a non-optional access; inside a
Loader the attached object is not resolved at construction and it threw.

Revealer takes implicitHeight from childrenRect, so anchoring its child
to its own centre closes a cycle once it sits in a Loader. ii-base hid it
by letting the layout drive the Revealer height directly.

Verified: qs -c souveraine reaches "Configuration Loaded" with no warning
naming any of these files.
2026-08-11 14:46:41 -04:00
Fimeg
391e239010 bar: one BarContent for every device, layout as data
ii-base and ii-phone each carried a 357-line BarContent to express eight
differences, all of them either "is this widget shown" or "which slot is
it in". No behaviour differed. Every bar edit had to be made twice or
diverge silently against the pin.

Widgets are now declared once as Components in a registry; each slot is a
Repeater over a list of widget names, so placement and order are data.
Config names a slot or a device profile picks it. "auto" derives the
profile from the same cramped-ness test behind useShortenedForm, so the
phone keeps its arrangement with no config file. Loaders are active only
when placed, so an unplaced widget is never constructed.

The agent island becomes a placeable widget rather than a mount smuggled
into UtilButtons: it reaches every device bar from one declaration.

ClockWidget is unified for the same reason. Its phone fork existed solely
to add customFormat, which BarContent now sets on every device.

bar.agentSessions was landing under background.widgets, not bar, so
Config.options.bar.agentSessions was always undefined and only the ?? true
fallback made the island appear wired. Moved, and merged into the existing
bar.indicators rather than declaring a second one.
2026-08-11 14:40:07 -04:00
Fimeg
d87d6117a4 patches: queue 0005, mount the agent island 2026-08-11 14:22:42 -04:00
Fimeg
b21184217e agent sessions: use shellPath convention for collector path 2026-08-11 14:21:37 -04:00
Fimeg
47ce2d1970 agent sessions: one collector, one island
Collector emits a single JSON envelope for every agent session (Souveraine,
Claude Code, Codex) and always exits 0; a failing provider reports
available:false rather than taking the envelope down.

AgentSessions.qml owns the cadence and projects the envelope. Transport is not
the contract: when the TASK-69 daemon lands, only the source changes.

Island is a morph host for the bar - dot on a cramped bar, pill where there is
room, derived from the same threshold BarContent uses.

Inert until registered in services/qmldir and mounted; see patches/0005.
2026-08-11 14:19:45 -04:00
Fimeg
928bd8d143 face: recreate a refused rig socket
Quickshell retains the failed QLocalSocket object, so toggling its requested state cannot reconnect. Replace the Socket body until the host answers.
2026-08-11 14:08:12 -04:00
Fimeg
5afa132ff4 face: keep knocking until the rig answers 2026-08-11 14:03:23 -04:00
Fimeg
e314d4fa23 face: expose the two live gaze links
Let the remote shell deploy accept the assets its caller already staged, so a successful composition does not fail after switching the tree.
2026-08-11 14:02:02 -04:00
Fimeg
8fd1a72edd face: reconnect to the rig after host startup 2026-08-11 13:33:09 -04:00
Fimeg
d290b12441 patches: queue QML compatibility fix 2026-08-11 09:37:09 -04:00
Fimeg
23cebc531d shell: keep typed segments QML-compatible 2026-08-11 09:35:53 -04:00
Fimeg
8c434dfb74 shell: render typed chat segments
Keep assistant, reasoning, tool-call, and tool-return frames structured through the sidebar delegate. Tool cards bind returns by wire id and fold their output by default.

Reasoned from the SSE contract and existing TUI renderer. Diff check passed. Untested against a running shell: Casey applies and reloads staged patches.
2026-08-11 09:13:50 -04:00
Fimeg
a8f7f62471 shell: stop sensor calls closing an open reasoning fence
A tool_call/tool_return arriving while a <think> block was open emitted its
own self-closing fence, whose </think> closed the outer block early. Every
reasoning token after that point rendered as prose, and the stray close left
the trailing assistant text mis-segmented. Append inside the open fence
instead; only open one when arriving in prose.
2026-08-11 09:13:50 -04:00
Fimeg
52f379f230 patches: queue typed chat segments 2026-08-11 08:56:08 -04:00
Fimeg
f17fa7c31b patches: queue think-fence collision fix 2026-08-11 08:10:39 -04:00
Fimeg
aaea09fdd6 shell: patches queue — agent stages, human applies
The composed config is symlinked into the repo and quickshell reloads on
write, so an agent editing QML edits the live shell mid-turn. Stage changes
as patches instead; the human applies and reloads on their own beat.

First in the queue: 0001-resume-offer — the agent-established hook offers
the latest thread instead of silently attaching it. Explicit resume paths
and the e4e6594 amnesia fix are untouched. Untested against a running
shell.
2026-08-10 23:04:59 -04:00