Update audit documentation and rules for live syncback enhancements

- Added a new section in `audit.md` for the Live Syncback Pipeline, detailing the plugin encoding, transport, and server handling processes.
- Included entries for newly introduced files `encodeHelpers.lua` and `encodeService.lua` in the audit documentation.
- Updated the audit checklist to cover live syncback parity and related concerns.
- Revised rule MDC files (`atlas-api.mdc`, `atlas-plugin.mdc`, `atlas-dedup.mdc`) to reflect recent changes, including the addition of `encodeHelpers.lua` and clarifications on `SyncbackConfirm`.
- Ensured comprehensive coverage of new test suites in the audit documentation.

These changes aim to enhance the clarity and accuracy of the audit documentation and rules, aligning them with the latest codebase updates.
This commit is contained in:
Joe 2026-02-19 00:22:49 -06:00
parent 49b4d8581f
commit 532425df9e
6 changed files with 356 additions and 97 deletions

View file

@ -408,7 +408,9 @@ end
| `init.lua` | Main batcher: accumulator, RenderStepped loop, pause/resume, deferred refs |
| `createPatchSet.lua` | Converts pending changes → PatchSet (passes instanceMap for Ref resolution) |
| `encodePatchUpdate.lua` | Encodes property updates including Ref properties via InstanceMap |
| `encodeInstance.lua` | Full instance encoding (for additions/syncback) |
| `encodeInstance.lua` | Full instance encoding (for additions/syncback); uses `encodeHelpers` for property iteration; includes duplicate detection helpers (`findDuplicateNames`, `hasDuplicateSiblings`, `isPathUnique`) |
| `encodeHelpers.lua` | Shared encoding helpers: `encodeAttributes`, `encodeTags`, `forEachEncodableProperty`. Used by `encodeInstance.lua` and `encodeService.lua`. Defines `SKIP_PROPERTIES` (Parent, Name, Archivable). |
| `encodeService.lua` | Encodes service-level properties/attributes/refs for live syncback; uses ObjectValue carriers for Ref properties |
| `encodeProperty.lua` | Single property value encoding via RbxDom |
| `propertyFilter.lua` | Property type filtering (only `UniqueId` blocked; `Ref` is allowed) |
@ -548,14 +550,14 @@ end
### encodeInstance.lua: Full Instance Encoding (Syncback/Additions)
Used when pulling new instances from Studio to filesystem. Duplicate-named instances are encoded and sent to the server; the server handles filesystem collisions via the dedup suffix system (`~N`).
Used when pulling new instances from Studio to filesystem. Uses `encodeHelpers.forEachEncodableProperty()` for property iteration (shared with `encodeService.lua`). Duplicate-named instances are encoded and sent to the server; the server handles filesystem collisions via the dedup suffix system (`~N`). Includes duplicate detection helpers (`findDuplicateNames`, `hasDuplicateSiblings`, `isPathUnique`).
```lua
function encodeInstance(instance, parentId, _skipPathCheck)
local properties = {}
encodeAttributes(instance, properties)
encodeTags(instance, properties)
Helpers.encodeAttributes(instance, properties)
Helpers.encodeTags(instance, properties)
if SCRIPT_CLASS_NAMES[instance.ClassName] then
local success, encoded = encodeProperty(instance, "Source", descriptor)
@ -563,24 +565,13 @@ function encodeInstance(instance, parentId, _skipPathCheck)
properties.Source = encoded
end
local classDescriptor = RbxDom.findClassDescriptor(instance.ClassName)
for propertyName, meta in classDescriptor.properties do
if SKIP_PROPERTIES[propertyName] then continue end
if SKIP_PROPERTIES_BY_CLASS[instance.ClassName]?[propertyName] then continue end
local isReadable = meta.scriptability == "ReadWrite" or meta.scriptability == "Read"
local doesSerialize = meta.serialization ~= "DoesNotSerialize"
if isReadable and doesSerialize then
local success, encoded = encodeProperty(instance, propertyName, descriptor)
if success and encoded ~= nil then
properties[propertyName] = encoded
end
Helpers.forEachEncodableProperty(instance.ClassName, SKIP_PROPERTIES_BY_CLASS, function(propertyName, descriptor)
local success, encoded = encodeProperty(instance, propertyName, descriptor)
if success and encoded ~= nil then
properties[propertyName] = encoded
end
end
end)
-- All children encoded (including those with duplicate names;
-- the server handles duplicates via dedup suffix system)
local children = {}
for _, child in instance:GetChildren() do
local encoded = encodeInstance(child, nil, true)

View file

@ -56,6 +56,7 @@ All three now have **`MatchingSession` caching** to avoid redundant recursive sc
| `plugin/src/Reconciler/trueEquals.lua` | Matching | `trueEquals` property comparison (Lua) |
| `src/change_processor.rs` | Integration | Dedup cleanup on deletion, VFS suppression, ref path updates |
| `src/web/api.rs` | Integration | `added_paths`, `syncback_updated_properties`, ref-to-attribute conversion |
| `plugin/src/ChangeBatcher/encodeHelpers.lua` | Encoding | Shared property filtering/encoding helpers (`encodeAttributes`, `encodeTags`, `forEachEncodableProperty`). Used by `encodeInstance.lua` and `encodeService.lua`. |
---

View file

@ -14,7 +14,7 @@ Built with Roact (React-like), handles WebSocket sync with server, patch applica
### Key Components
**1. UI Layer** (`App/`)
- **init.lua** - Root component, manages connection state, auto-reconnect, sync reminders, playtest server auto-connect
- **init.lua** - Root component, manages connection state, auto-reconnect, sync reminders, playtest server auto-connect. Also renders `SyncbackConfirm` floating dialog (StudioPluginGui with `isEphemeral=true`, not a StatusPage file). Contains `performSyncback()` and `SYNCBACK_SERVICES` constant.
- **Theme.lua** - Studio-matched color palette (auto light/dark)
- **Page.lua** - Page wrapper component
- **Components/** - Reusable UI components
@ -28,7 +28,6 @@ Built with Roact (React-like), handles WebSocket sync with server, patch applica
- `NotConnected.lua` - Connection form (host/port input), "Syncback" button (Danger style)
- `Connecting.lua` - Loading screen
- `Confirming.lua` - Patch confirmation dialog with push/pull/ignore per-node selections
- `SyncbackConfirm` - Floating dialog for live syncback confirmation (rendered by `App/init.lua`)
- `Connected.lua` - Status display with patch history
- `Error.lua` - Error display
- `Settings/` - Settings UI (`init.lua`, `Setting.lua`)
@ -57,7 +56,8 @@ Built with Roact (React-like), handles WebSocket sync with server, patch applica
- **init.lua** - Main batcher: accumulates changes every 200ms, pause/resume, deferred Ref resolution
- **createPatchSet.lua** - Converts pending changes to PatchSet
- **encodePatchUpdate.lua** - Encodes property updates including Ref properties via InstanceMap
- **encodeInstance.lua** - Full instance encoding (for additions/syncback); includes duplicate detection helpers (`findDuplicateNames`, `hasDuplicateSiblings`, `isPathUnique`)
- **encodeInstance.lua** - Full instance encoding (for additions/syncback); uses `encodeHelpers` for property iteration; includes duplicate detection helpers (`findDuplicateNames`, `hasDuplicateSiblings`, `isPathUnique`)
- **encodeHelpers.lua** - Shared property encoding helpers (`encodeAttributes`, `encodeTags`, `forEachEncodableProperty`). Used by `encodeInstance.lua` and `encodeService.lua`. Defines `SKIP_PROPERTIES` (Parent, Name, Archivable).
- **encodeService.lua** - Encodes service-level properties/attributes/refs for live syncback; uses ObjectValue carriers for Ref properties
- **encodeProperty.lua** - Single property value encoding via RbxDom
- **propertyFilter.lua** - Property type filtering (only `UniqueId` blocked; `Ref` is allowed)