Commit graph

99 commits

Author SHA1 Message Date
Libby
f891404ee3 node-actions.md: point to the parked design tag
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-10 23:15:55 +00:00
47d27271e7 Merge pull request 'Blender add-on: createObject and renderStill refuse what they cannot do' (#8) from libby/blender-refusals into main 2026-11-10 23:14:05 +00:00
Libby
01d25c6bf9 Blender createObject: pin whitespace meshType refusal, document meshType and null objectType
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-10 23:13:57 +00:00
Libby
944ea4a1ec Merge remote-tracking branch 'origin/main' into libby/refusals-fix
# Conflicts:
#	surfaces/blender/tests/test_scene_actions.py
2026-11-10 18:01:45 +00:00
730ceb9e0e Blender add-on: exportGltf action (#7) 2026-11-10 18:01:28 +00:00
8cebec6f3c Blender assignMaterial: colour, idempotent slot, malformed colour refused (#6) 2026-11-10 18:00:37 +00:00
Libby
6b7d6ae9e2 blender: renderStill refuses GL engines headless when libEGL is not loadable
BLENDER_WORKBENCH and BLENDER_EEVEE aborted the whole Blender process inside
bpy.ops.render.render with no receipt. The probe is cached, Linux only, and a
module-level function so tests replace it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-10 17:55:38 +00:00
Libby
ece40040f4 blender: createObject refuses unknown objectType and non-cube meshType
TEXT and CURVE used to fall through to an EMPTY with an accepted receipt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-10 17:55:38 +00:00
6995eabf51 Blender add-on: geometry node graph actions, modifier inputs, evaluated snapshot (#5) 2026-11-10 17:54:18 +00:00
6f0e70042d Blender add-on tests: token-guard test no longer pins the store spelling (#9) 2026-11-10 17:42:46 +00:00
acd9a583cd Merge pull request 'Blender add-on: pass CultMeshGrantAllWrites() to its served node' (#4) from libby/blender-grant-peer-writes into main 2026-11-07 19:19:41 +00:00
Libby
a98ccacb37 Blender add-on docs: grant-all lets a peer write any registered document
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 19:14:21 +00:00
Libby
221f59b754 Blender add-on: grant peer writes explicitly to its served node
cultmesh_py (CultLib GameCult/CultLib#33) refuses peer puts and deletes unless a
write authority grants them. The add-on's clients put command intents, and the
session token guard already authenticates them, so the target passes
CultMeshGrantAllWrites() when cultmesh_py has it. Older cultmesh_py already
accepts every write and is left alone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 19:08:33 +00:00
82ed1e73cb Merge pull request 'Blender add-on: importGltf, setCamera, setLight, setWorld, renderStill' (#2) from libby/blender-scene-actions into main 2026-11-07 15:13:26 +00:00
Libby
dbd4cc05d1 scene actions: device-name spellings, missing glTF references, link message kept, no folders on refused render
- check_relative: spaces before the first dot are dropped (CON .txt), superscript COM/LPT digits are device names.
- gltf_references refuses a reference to a missing file; drops the broad ValueError catch and redundant relative_to so the specific refusal (a link) reaches the receipt.
- _render_still makes folders only after every Blender-side refusal (unknown engine used to leave them behind).
- Tests for each.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 15:10:58 +00:00
Libby
5adff0f8a2 scene actions: junction refusal on Windows, direct path-rule tests, live junction smoke, TOCTOU doc
- resolve_inside maps OSError from resolving a component (WinError 448 on a mklink /J junction) to a link refusal.
- Direct check_relative test for '..' and NUL; OSError mapping test.
- headless_smoke.py makes real junctions on Windows (outside and inside the root) and an existing-output case.
- install.md documents the path rules and the residual TOCTOU.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 15:05:48 +00:00
Libby
72b52b5d0e scene actions: gltf reference check, relative-only names, link walk, no-overwrite output
WIP for review fixes, tests pass (61); mutation confirmation and Starfire re-run pending.

- importGltf parses .gltf JSON and .glb's JSON chunk, checks every buffers/images uri.
- Names are relative plain paths: no drive, UNC, extended, ':' (ADS), '..', device names.
- No symlink/junction component under the root; output must not already exist.
- Path and file stamps re-checked right before use; residual TOCTOU documented in code.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 13:20:30 +00:00
Libby
4b2fefa368 renderStill: ask Blender for the engine by assignment; add headless live smoke
Found by running the actions on Blender 5.2.3 headless: the render engine enum is
dynamic, bl_rna lists only BLENDER_EEVEE, so CYCLES and WORKBENCH were refused.
The fake in the tests now behaves like the real enum. surfaces/blender/tests/live/
headless_smoke.py runs every scene action against real bpy.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 13:14:47 +00:00
Libby
e9a780569f Merge main (server hardening, PR #1) into blender-scene-actions
Resolved blender_target.py: both the server-guard fields and the action directories kept.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 12:52:59 +00:00
679020d858 Merge pull request 'Blender add-on: server hardening (opt-in session token, intent purge, bind guard)' (#1) from libby/blender-server-hardening into main 2026-11-07 12:52:41 +00:00
Libby
2f38d0c9c2 Blender add-on: token never drawn, UI wiring tests, DELETE shard-log test
- Panel offers only the Copy Session Token button; the token is not drawn.
- Fake-bpy tests: allow_non_loopback carries an update callback that stops a running
  non-loopback server; copy operator writes the clipboard; the panel never draws the token.
- Real-server test: a DELETE with shardId and a valid token leaves no token in the shard log.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 12:52:40 +00:00
Libby
d1501e8fdb Blender add-on hardening: strip token before the store, bind enforcement, loaded-module display
- The guarded server removes sessionToken from put/delete messages before the store,
  which copies envelope fields into the shard log it serves.
- Copy Session Token operator.
- Panel shows cultmesh_py's loaded __file__, not the preference path.
- Unticking Allow Non-Loopback (and any refused start) stops a running non-loopback server.
- stop_server revokes, purges and clears state even if the socket stop raises.
- Tests: shard-log token leak on the real server, node half of the start purge, purge
  persisted across reopening the .ccmp, allow=True through start_server, finally-path.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 12:50:00 +00:00
Libby
2246584416 Blender add-on: importGltf, setCamera, setLight, setWorld, renderStill actions
Paths for importGltf and renderStill are confined to the Import Directory and
Render Output Directory preferences (empty disables the action; .. , absolute
paths and escaping symlinks are refused). Every field is validated before bpy is
touched. renderStill restores render settings afterwards. Tests use a fake bpy;
Blender was not run.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 12:43:45 +00:00
Libby
82c94cf92a Blender add-on: server hardening (opt-in session token, purge, bind guard)
- Optional per-session token (preference, default off): random secrets token at
  Start Server, shown in the panel, required in the sessionToken envelope field on
  every document put and delete, revoked on Stop, never persisted.
- Always on: queued command intents (node records and debug command JSONs) are
  purged on server start and stop; the panel shows the bind address and the
  cultlib_py_src path; a non-loopback Serve Host is refused unless the
  Allow Non-Loopback Bind preference is ticked, with a panel warning while running.
- Tests without Blender, plus real cultmesh_py server tests when CULTLIB_PACKAGES is set.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 12:41:38 +00:00
Meta Vens
be0cc3683f Brokkr advertisement: drop Eve surface URIs and eve.*.publish capabilities; Eve is deprecated
Per thing2:ruling:eve-dashboards-quarantined. Removes eveSurfaces from the provider advertisement and its schema, the two surface URIs, the eve.gui/eve.tui publish capabilities, and Eve wording in docs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:14:59 +02:00
Meta Vens
e2f1cc7942 Pin CultLib 2.0.0 for builds
Directory.Build.props names CultLibRoot (CULTLIB_ROOT, else the sibling checkout) and pins CultLibRevision to cultlib-unity-v2.0.0 (42dce361). Directory.Build.targets fails the build unless that checkout is at the pin and clean, as Aetheria's guard does. Project references use CultLibRoot.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 19:46:07 +02:00
Meta Vens
7e18cb1bb5 Brokkr msgpack target r2: no receipt converter; a daemon-written JSON store at window time is a stop-and-report
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 05:17:39 +02:00
Meta Vens
4781a8248e Brokkr msgpack payloads: campaign target (brokkr-msgpack)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 05:13:00 +02:00
Meta Vens
f97d4dcbb7 Research: Blender MCP servers as the capability bar for Brokkr
Eyes pass 2026-10-10: tools, limits and security posture of the official
Blender Lab MCP, the community BlenderMCP and Blender Agent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:00:16 +02:00
Meta Vens
1357705b11 Brokkr map: record A1-A5 landing and the pass 4 follow-ups
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 18:38:51 +02:00
Meta Vens
90892f0e79 Merge Brokkr agent access A1-A5 and the enable race fixes
The editor service is the one command owner, the sink is off by default,
command ids are single-use, and stale intents expire on enable in one
conditional cache commit. Soul pass 4 verdict: merge. Recorded follow-up:
TryCommitEnableAsync does not retry when a concurrent PutAsync leaves
staged writes; unreachable on Unity's main thread and fails safe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 18:38:15 +02:00
Meta Vens
052808773e Tests follow the commit-per-write store: two enable flushes, verdict survives a failed fsync
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 18:00:49 +02:00
Meta Vens
121fa329e2 Soul pass 3: conditional enable in Runtime, receipt floor, one write path
- The enable commit is conditional (ExpectUnchanged) and lives in the new
  Runtime BrokkrCommandStore, with the pull-recompute-retry loop in
  BrokkrCommandDrain.EnableAsync, so the tests exercise the shipped code. An
  intent landing between the pull and the commit is expired, not run; eight
  refusals in a row fail the enable loudly with the sink off. The probe is now
  a thin fault-injecting wrapper over the real store, not a copy of it.
- Every editor write to the command lane is one cache commit; durable shard
  logs are off (no server, no reader).
- No receipt is pruned before ten minutes, whatever the count, and the CLI
  refuses a wait over five minutes. Fixed the comments that claimed otherwise.
- Pending and Prunable count a document only under the key its own id names.
- README and snapshot comment: the token stops stale EditorPrefs, it does not
  authenticate writers; a restored or sync-conflict copy of the editor's own
  store can rerun answered intents.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 17:52:34 +02:00
Meta Vens
878d6a52b5 Unity README: store-tied enable, receipt cap, interrupted is not idempotent
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 17:14:52 +02:00
Meta Vens
35d4f1644a State the flood test budgets and where the enable cost comes from
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 17:04:18 +02:00
Meta Vens
8651584f9d Commit the enable expiry and the prune as single cache batches
Database.PutAsync appends a mutation-log entry per record, so expiring 2000
intents took 17 s even with one flush. The drain's two bulk writes are now
atomic CultCache commits, so the enable cannot half-apply and the cost is per
commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 17:02:10 +02:00
Meta Vens
95e5931b2b Fix the probe comment that swallowed a member declaration
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:57:09 +02:00
Meta Vens
9f5e8fbf3c Decide "before the enable" by the store, batch the expiry, bound receipts
Soul pass 2 findings S1, S2, S3, S4.

- Enabling the sink is the drain's EnableAsync: every intent already in the
  store gets an "expired" receipt and the enable marker is written, all in one
  flush. No decision compares StoredAt with a clock any more, so a fast
  writer clock and the Rust daemon's secs.nanosZ stamps stop mattering.
- The operator's EditorPrefs hold a token, and the sink runs only while the
  store carries the marker with that token. A re-clone or a copied .brokkr has
  no such marker, so a stale "enabled" authorizes nothing and the editor drops
  it. The epoch and agentCommandsEnabledAt (host snapshot key 19) are gone.
- Selection is one pass over the store per tick (Pending), not a copy and sort
  per intent.
- Receipts are capped at the newest 1000, pruned 128 pairs per tick with the
  intent deleted before its receipt.
- A marker that could not be written is withdrawn, so the intent reads as
  never started and is retried, not "interrupted".
- The drain writes through IBrokkrCommandStore; puts stage and one flush makes
  them durable.
- The CLI timeout text no longer says the intent "stays written" without the
  expiry caveat; the check-then-write window on --command-id is documented.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:56:33 +02:00
Meta Vens
24a7de3788 Unity README: expiry, attempt markers, the per-tick bound and CLI exit codes
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:26:17 +02:00
Meta Vens
350c5626c3 brokkr-command: say "cannot be opened", and pin the catch-all with a mid-flight failure
A store that fails to open is not always unreadable (a held lock does it too),
so the message says what happened. The catch-all's test now corrupts the store
after the CLI opened it, which the open's own handling cannot see.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:25:15 +02:00
Meta Vens
96904b0b7c wip catch-all probe 2026-09-29 16:19:05 +02:00
Meta Vens
de2ab2661a Pin the CLI's catch-all exit and drop a test that only exercised the harness
The sink-off gate lives in the Unity service, not the drain, so the harness test
proved nothing about the machine. The new test reaches the CLI's last-resort
exit code with a failure that happens after the store opened.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:18:07 +02:00
Meta Vens
b451cddf1d brokkr-command: map every failure to exit 0/1/2, refuse a reused command id
- Any exception now exits 2 with a message. An empty or legacy store fails with
  a message that names the path instead of aborting with 134.
- A --command-id that already has a receipt is refused with exit 2, so a stale
  receipt is never reported as the answer to a new intent.
- The wait treats the editor's "attempted" marker as not yet a verdict.
- The action theory passes --output so captureEditorView clears admission now
  that the harness runs the real policy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:16:50 +02:00
Meta Vens
73f7926ad0 Make the editor service the only writer of unity/host/current
The window republished a snapshot it had captured earlier, which could carry a
stale agentCommandsEnabled. Publish Mirror and Auto Publish now ask the service
to capture and publish a fresh one; the window keeps the returned snapshot for
display only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:16:50 +02:00
Meta Vens
c694f582c2 Drain intents through one class: attempt marker, enable epoch, per-tick bound
BrokkrCommandDrain owns every rule between a pending intent and its receipt.
The service and the scenario harness now run the same drain instead of two
copies of the loop.

- An "attempted" receipt is written and flushed before Execute. A crash or a
  failing final receipt write can no longer re-run an intent; the next drain
  rewrites a leftover marker as "interrupted" and the operator decides.
- The host snapshot carries the sink's enable epoch. Intents stored before the
  latest enable get an "expired" receipt and never run (operator ruling
  2026-09-30).
- One drain handles at most 16 intents, expired and denied ones included.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:16:41 +02:00
Meta Vens
9ab4ab4519 Make a ledger regression fail the scenario harness instead of hanging it
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 15:49:21 +02:00
Meta Vens
c75fc4edc7 Write the NUL path case as an escape
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 15:39:43 +02:00
Meta Vens
c5775e6499 Pin the capture directory spelling, a leading colon and an invalid path character
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 15:39:37 +02:00
Meta Vens
bb60fdfbce Pin the sink-off report in readHost and the timeout hint, and the a/../b capture path
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 14:53:44 +02:00
Meta Vens
673da3e62f A5: advertise the three editor capabilities the Unity actions now provide
editor.assets.refresh, editor.lifecycle.write and editor.view.capture join
the Unity surface, in the provider contract and the advertisement test. The
donor's prefab mirror rows are not taken; that pipeline is parked.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 14:49:09 +02:00