docs: sync Silo server documentation
Some checks failed
Deploy Docs / build-and-deploy (push) Successful in 48s
Build and Test / build (push) Has been cancelled

Auto-synced from kindred/silo main branch.
This commit is contained in:
Kindred Bot
2026-02-15 23:12:55 +00:00
parent 7b1662a3d1
commit d497471ed3
7 changed files with 1971 additions and 383 deletions

246
docs/src/silo-server/DAG.md Normal file
View File

@@ -0,0 +1,246 @@
# Dependency DAG Specification
**Status:** Draft
**Last Updated:** 2026-02-13
---
## 1. Purpose
The Dependency DAG is a server-side graph that tracks how features, constraints, and assembly relationships depend on each other. It enables three capabilities described in [MULTI_USER_EDITS.md](MULTI_USER_EDITS.md):
1. **Interference detection** -- comparing dependency cones of concurrent edit sessions to classify conflicts as none, soft, or hard before the user encounters them.
2. **Incremental validation** -- marking changed nodes dirty and propagating only through the affected subgraph, using input-hash memoization to stop early when inputs haven't changed.
3. **Structured merge safety** -- walking the DAG to determine whether concurrent edits share upstream dependencies, deciding if auto-merge is safe or manual review is required.
---
## 2. Two-Tier Model
Silo maintains two levels of dependency graph:
### 2.1 BOM DAG (existing)
The assembly-to-part relationship graph already stored in the `relationships` table. Each row represents a parent item containing a child item with a quantity and relationship type (`component`, `alternate`, `reference`). This graph is queried via `GetBOM`, `GetExpandedBOM`, `GetWhereUsed`, and `HasCycle` in `internal/db/relationships.go`.
The BOM DAG is **not modified** by this specification. It continues to serve its existing purpose.
### 2.2 Feature DAG (new)
A finer-grained graph stored in `dag_nodes` and `dag_edges` tables. Each node represents a feature within a single item's revision -- a sketch, pad, fillet, pocket, constraint, body, or part-level container. Edges represent "depends on" relationships: if Pad003 depends on Sketch001, an edge runs from Sketch001 to Pad003.
The feature DAG is populated by clients (silo-mod) when users save, or by runners after compute jobs. Silo stores and queries it but does not generate it -- the Create client has access to the feature tree and is the authoritative source.
### 2.3 Cross-Item Edges
Assembly constraints often reference geometry on child parts (e.g., "mate Face6 of PartA to Face2 of PartB"). These cross-item dependencies are stored in `dag_cross_edges`, linking a node in one item to a node in another. Each cross-edge optionally references the `relationships` row that establishes the BOM connection.
---
## 3. Data Model
### 3.1 dag_nodes
| Column | Type | Description |
|--------|------|-------------|
| `id` | UUID | Primary key |
| `item_id` | UUID | FK to `items.id` |
| `revision_number` | INTEGER | Revision this DAG snapshot belongs to |
| `node_key` | TEXT | Feature name from Create (e.g., `Sketch001`, `Pad003`, `Body`) |
| `node_type` | TEXT | One of: `sketch`, `pad`, `pocket`, `fillet`, `chamfer`, `constraint`, `body`, `part`, `datum`, `mirror`, `pattern`, `boolean` |
| `properties_hash` | TEXT | SHA-256 of the node's parametric inputs (sketch coordinates, fillet radius, constraint values). Used for memoization -- if the hash hasn't changed, validation can skip this node. |
| `validation_state` | TEXT | One of: `clean`, `dirty`, `validating`, `failed` |
| `validation_msg` | TEXT | Error message when `validation_state = 'failed'` |
| `metadata` | JSONB | Type-specific data (sketch coords, feature params, constraint definitions) |
| `created_at` | TIMESTAMPTZ | Row creation time |
| `updated_at` | TIMESTAMPTZ | Last state change |
**Uniqueness:** `(item_id, revision_number, node_key)` -- one node per feature per revision.
### 3.2 dag_edges
| Column | Type | Description |
|--------|------|-------------|
| `id` | UUID | Primary key |
| `source_node_id` | UUID | FK to `dag_nodes.id` -- the upstream node |
| `target_node_id` | UUID | FK to `dag_nodes.id` -- the downstream node that depends on source |
| `edge_type` | TEXT | `depends_on` (default), `references`, `constrains` |
| `metadata` | JSONB | Optional edge metadata |
**Direction convention:** An edge from A to B means "B depends on A". A is upstream, B is downstream. Forward-cone traversal from A walks edges where A is the source.
**Uniqueness:** `(source_node_id, target_node_id, edge_type)`.
**Constraint:** `source_node_id != target_node_id` (no self-edges).
### 3.3 dag_cross_edges
| Column | Type | Description |
|--------|------|-------------|
| `id` | UUID | Primary key |
| `source_node_id` | UUID | FK to `dag_nodes.id` -- node in item A |
| `target_node_id` | UUID | FK to `dag_nodes.id` -- node in item B |
| `relationship_id` | UUID | FK to `relationships.id` (nullable) -- the BOM entry connecting the two items |
| `edge_type` | TEXT | `assembly_ref` (default) |
| `metadata` | JSONB | Reference details (face ID, edge ID, etc.) |
**Uniqueness:** `(source_node_id, target_node_id)`.
---
## 4. Validation States
Each node has a `validation_state` that tracks whether its computed geometry is current:
| State | Meaning |
|-------|---------|
| `clean` | Node's geometry matches its `properties_hash`. No recompute needed. |
| `dirty` | An upstream change has propagated to this node. Recompute required. |
| `validating` | A compute job is currently revalidating this node. |
| `failed` | Recompute failed. `validation_msg` contains the error. |
### 4.1 State Transitions
```
clean → dirty (upstream change detected, or MarkDirty called)
dirty → validating (compute job claims this node)
validating → clean (recompute succeeded, properties_hash updated)
validating → failed (recompute produced an error)
failed → dirty (upstream change detected, retry possible)
dirty → clean (properties_hash matches previous -- memoization shortcut)
```
### 4.2 Dirty Propagation
When a node is marked dirty, all downstream nodes in its forward cone are also marked dirty. This is done atomically in a single recursive CTE:
```sql
WITH RECURSIVE forward_cone AS (
SELECT $1::uuid AS node_id
UNION
SELECT e.target_node_id
FROM dag_edges e
JOIN forward_cone fc ON fc.node_id = e.source_node_id
)
UPDATE dag_nodes SET validation_state = 'dirty', updated_at = now()
WHERE id IN (SELECT node_id FROM forward_cone)
AND validation_state = 'clean';
```
### 4.3 Memoization
Before marking a node dirty, the system can compare the new `properties_hash` against the stored value. If they match, the change did not affect this node's inputs, and propagation stops. This is the memoization boundary described in MULTI_USER_EDITS.md Section 5.2.
---
## 5. Graph Queries
### 5.1 Forward Cone
Returns all nodes downstream of a given node -- everything that would be affected if the source node changes. Used for interference detection: if two users' forward cones overlap, there is potential interference.
```sql
WITH RECURSIVE forward_cone AS (
SELECT target_node_id AS node_id
FROM dag_edges WHERE source_node_id = $1
UNION
SELECT e.target_node_id
FROM dag_edges e
JOIN forward_cone fc ON fc.node_id = e.source_node_id
)
SELECT n.* FROM dag_nodes n JOIN forward_cone fc ON n.id = fc.node_id;
```
### 5.2 Backward Cone
Returns all nodes upstream of a given node -- everything the target node depends on.
### 5.3 Dirty Subgraph
Returns all nodes for a given item where `validation_state != 'clean'`, along with their edges. This is the input to an incremental validation job.
### 5.4 Cycle Detection
Before adding an edge, check that it would not create a cycle. Uses the same recursive ancestor-walk pattern as `HasCycle` in `internal/db/relationships.go`.
---
## 6. DAG Sync
Clients push the full feature DAG to Silo via `PUT /api/items/{partNumber}/dag`. The sync payload is a JSON document:
```json
{
"revision": 3,
"nodes": [
{
"key": "Sketch001",
"type": "sketch",
"properties_hash": "a1b2c3...",
"metadata": {
"coordinates": [[0, 0], [10, 0], [10, 5]],
"constraints": ["horizontal", "vertical"]
}
},
{
"key": "Pad003",
"type": "pad",
"properties_hash": "d4e5f6...",
"metadata": {
"length": 15.0,
"direction": [0, 0, 1]
}
}
],
"edges": [
{
"source": "Sketch001",
"target": "Pad003",
"type": "depends_on"
}
]
}
```
The server processes this within a single transaction:
1. Upsert all nodes (matched by `item_id + revision_number + node_key`).
2. Replace all edges for this item/revision.
3. Compare new `properties_hash` values against stored values to detect changes.
4. Mark changed nodes and their forward cones dirty.
5. Publish `dag.updated` SSE event.
---
## 7. Interference Detection
When a user registers an edit context (MULTI_USER_EDITS.md Section 3.1), the server:
1. Looks up the node(s) being edited by `node_key` within the item's current revision.
2. Computes the forward cone for those nodes.
3. Compares the cone against all active edit sessions' cones.
4. Classifies interference:
- **No overlap** → no interference, fully concurrent.
- **Overlap, different objects** → soft interference, visual indicator via SSE.
- **Same object, same edit type** → hard interference, edit blocked.
---
## 8. REST API
All endpoints are under `/api/items/{partNumber}` and require authentication.
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `GET` | `/dag` | viewer | Get full feature DAG for current revision |
| `GET` | `/dag/forward-cone/{nodeKey}` | viewer | Get forward dependency cone |
| `GET` | `/dag/dirty` | viewer | Get dirty subgraph |
| `PUT` | `/dag` | editor | Sync full feature tree (from client or runner) |
| `POST` | `/dag/mark-dirty/{nodeKey}` | editor | Manually mark a node and its cone dirty |
---
## 9. References
- [MULTI_USER_EDITS.md](MULTI_USER_EDITS.md) -- Full multi-user editing specification
- [WORKERS.md](WORKERS.md) -- Worker/runner system that executes validation jobs
- [ROADMAP.md](ROADMAP.md) -- Tier 0 Dependency DAG entry

View File

@@ -0,0 +1,395 @@
# DAG Client Integration Contract
**Status:** Draft
**Last Updated:** 2026-02-13
This document describes what silo-mod and Headless Create runners need to implement to integrate with the Silo dependency DAG and worker system.
---
## 1. Overview
The DAG system has two client-side integration points:
1. **silo-mod workbench** (desktop) -- pushes DAG data to Silo on save or revision create.
2. **silorunner + silo-mod** (headless) -- extracts DAGs, validates features, and exports geometry as compute jobs.
Both share the same Python codebase in the silo-mod repository. Desktop users call the code interactively; runners call it headlessly via `create --console`.
---
## 2. DAG Sync Payload
Clients push feature trees to Silo via:
```
PUT /api/items/{partNumber}/dag
Authorization: Bearer <user_token or runner_token>
Content-Type: application/json
```
### 2.1 Request Body
```json
{
"revision_number": 3,
"nodes": [
{
"node_key": "Sketch001",
"node_type": "sketch",
"properties_hash": "a1b2c3d4e5f6...",
"metadata": {
"label": "Base Profile",
"constraint_count": 12
}
},
{
"node_key": "Pad001",
"node_type": "pad",
"properties_hash": "f6e5d4c3b2a1...",
"metadata": {
"label": "Main Extrusion",
"length": 25.0
}
}
],
"edges": [
{
"source_key": "Sketch001",
"target_key": "Pad001",
"edge_type": "depends_on"
}
]
}
```
### 2.2 Field Reference
**Nodes:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `node_key` | string | yes | Unique within item+revision. Use Create's internal object name (e.g. `Sketch001`, `Pad003`). |
| `node_type` | string | yes | One of: `sketch`, `pad`, `pocket`, `fillet`, `chamfer`, `constraint`, `body`, `part`, `datum`. |
| `properties_hash` | string | no | SHA-256 hex digest of the node's parametric inputs. Used for memoization. |
| `validation_state` | string | no | One of: `clean`, `dirty`, `validating`, `failed`. Defaults to `clean`. |
| `metadata` | object | no | Arbitrary key-value pairs for display or debugging. |
**Edges:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `source_key` | string | yes | The node that is depended upon. |
| `target_key` | string | yes | The node that depends on the source. |
| `edge_type` | string | no | One of: `depends_on` (default), `references`, `constrains`. |
**Direction convention:** Edges point from dependency to dependent. If Pad001 depends on Sketch001, the edge is `source_key: "Sketch001"`, `target_key: "Pad001"`.
### 2.3 Response
```json
{
"synced": true,
"node_count": 15,
"edge_count": 14
}
```
---
## 3. Computing properties_hash
The `properties_hash` enables memoization -- if a node's inputs haven't changed since the last validation, it can be skipped. Computing it:
```python
import hashlib
import json
def compute_properties_hash(feature_obj):
"""Hash the parametric inputs of a Create feature."""
inputs = {}
if feature_obj.TypeId == "Sketcher::SketchObject":
# Hash geometry + constraints
inputs["geometry_count"] = feature_obj.GeometryCount
inputs["constraint_count"] = feature_obj.ConstraintCount
inputs["geometry"] = str(feature_obj.Shape.exportBrep())
elif feature_obj.TypeId == "PartDesign::Pad":
inputs["length"] = feature_obj.Length.Value
inputs["type"] = str(feature_obj.Type)
inputs["reversed"] = feature_obj.Reversed
inputs["sketch"] = feature_obj.Profile[0].Name
# ... other feature types
canonical = json.dumps(inputs, sort_keys=True)
return hashlib.sha256(canonical.encode()).hexdigest()
```
The exact inputs per feature type are determined by what parametric values affect the feature's geometry. Include anything that, if changed, would require recomputation.
---
## 4. Feature Tree Walking
To extract the DAG from a Create document:
```python
import FreeCAD
def extract_dag(doc):
"""Walk a Create document and return nodes + edges."""
nodes = []
edges = []
for obj in doc.Objects:
# Skip non-feature objects
if not hasattr(obj, "TypeId"):
continue
node_type = classify_type(obj.TypeId)
if node_type is None:
continue
nodes.append({
"node_key": obj.Name,
"node_type": node_type,
"properties_hash": compute_properties_hash(obj),
"metadata": {
"label": obj.Label,
"type_id": obj.TypeId,
}
})
# Walk dependencies via InList (objects this one depends on)
for dep in obj.InList:
if hasattr(dep, "TypeId") and classify_type(dep.TypeId):
edges.append({
"source_key": dep.Name,
"target_key": obj.Name,
"edge_type": "depends_on",
})
return nodes, edges
def classify_type(type_id):
"""Map Create TypeIds to DAG node types."""
mapping = {
"Sketcher::SketchObject": "sketch",
"PartDesign::Pad": "pad",
"PartDesign::Pocket": "pocket",
"PartDesign::Fillet": "fillet",
"PartDesign::Chamfer": "chamfer",
"PartDesign::Body": "body",
"Part::Feature": "part",
"Sketcher::SketchConstraint": "constraint",
}
return mapping.get(type_id)
```
---
## 5. When to Push DAG Data
Push the DAG to Silo in these scenarios:
| Event | Trigger | Who |
|-------|---------|-----|
| User saves in silo-mod | On save callback | Desktop silo-mod workbench |
| User creates a revision | After `POST /api/items/{pn}/revisions` succeeds | Desktop silo-mod workbench |
| Runner extracts DAG | After `create-dag-extract` job completes | silorunner via `PUT /api/runner/jobs/{id}/dag` |
| Runner validates | After `create-validate` job, push updated validation states | silorunner via `PUT /api/runner/jobs/{id}/dag` |
---
## 6. Runner Entry Points
silo-mod must provide these Python entry points for headless invocation:
### 6.1 silo.runner.dag_extract
Extracts the feature DAG from a Create file and writes it as JSON.
```python
# silo/runner.py
def dag_extract(input_path, output_path):
"""
Extract feature DAG from a Create file.
Args:
input_path: Path to the .kc (Kindred Create) file.
output_path: Path to write the JSON output.
Output JSON format:
{
"nodes": [...], // Same format as DAG sync payload
"edges": [...]
}
"""
doc = FreeCAD.openDocument(input_path)
nodes, edges = extract_dag(doc)
with open(output_path, 'w') as f:
json.dump({"nodes": nodes, "edges": edges}, f)
FreeCAD.closeDocument(doc.Name)
```
### 6.2 silo.runner.validate
Rebuilds all features and reports pass/fail per node.
```python
def validate(input_path, output_path):
"""
Validate a Create file by rebuilding all features.
Output JSON format:
{
"valid": true/false,
"nodes": [
{
"node_key": "Pad001",
"state": "clean", // or "failed"
"message": null, // error message if failed
"properties_hash": "..."
}
]
}
"""
doc = FreeCAD.openDocument(input_path)
doc.recompute()
results = []
all_valid = True
for obj in doc.Objects:
if not hasattr(obj, "TypeId"):
continue
node_type = classify_type(obj.TypeId)
if node_type is None:
continue
state = "clean"
message = None
if hasattr(obj, "isValid") and not obj.isValid():
state = "failed"
message = f"Feature {obj.Label} failed to recompute"
all_valid = False
results.append({
"node_key": obj.Name,
"state": state,
"message": message,
"properties_hash": compute_properties_hash(obj),
})
with open(output_path, 'w') as f:
json.dump({"valid": all_valid, "nodes": results}, f)
FreeCAD.closeDocument(doc.Name)
```
### 6.3 silo.runner.export
Exports geometry to STEP, IGES, or other formats.
```python
def export(input_path, output_path, format="step"):
"""
Export a Create file to an external format.
Args:
input_path: Path to the .kc file.
output_path: Path to write the exported file.
format: Export format ("step", "iges", "stl", "obj").
"""
doc = FreeCAD.openDocument(input_path)
import Part
shapes = [obj.Shape for obj in doc.Objects if hasattr(obj, "Shape")]
compound = Part.makeCompound(shapes)
format_map = {
"step": "STEP",
"iges": "IGES",
"stl": "STL",
"obj": "OBJ",
}
Part.export([compound], output_path)
FreeCAD.closeDocument(doc.Name)
```
---
## 7. Headless Invocation
The `silorunner` binary shells out to Create (with silo-mod installed):
```bash
# DAG extraction
create --console -e "from silo.runner import dag_extract; dag_extract('/tmp/job/part.kc', '/tmp/job/dag.json')"
# Validation
create --console -e "from silo.runner import validate; validate('/tmp/job/part.kc', '/tmp/job/result.json')"
# Export
create --console -e "from silo.runner import export; export('/tmp/job/part.kc', '/tmp/job/output.step', 'step')"
```
**Prerequisites:** The runner host must have:
- Headless Create installed (Kindred's fork of FreeCAD)
- silo-mod installed as a Create addon (so `from silo.runner import ...` works)
- No display server required -- `--console` mode is headless
---
## 8. Validation Result Handling
After a runner completes a `create-validate` job, it should:
1. Read the result JSON.
2. Push updated validation states via `PUT /api/runner/jobs/{jobID}/dag`:
```json
{
"revision_number": 3,
"nodes": [
{"node_key": "Sketch001", "node_type": "sketch", "validation_state": "clean", "properties_hash": "abc..."},
{"node_key": "Pad001", "node_type": "pad", "validation_state": "failed", "properties_hash": "def..."}
],
"edges": [
{"source_key": "Sketch001", "target_key": "Pad001"}
]
}
```
3. Complete the job via `POST /api/runner/jobs/{jobID}/complete` with the summary result.
---
## 9. SSE Events
Clients should listen for these events on `GET /api/events`:
| Event | Payload | When |
|-------|---------|------|
| `dag.updated` | `{item_id, part_number, revision_number, node_count, edge_count}` | After any DAG sync |
| `dag.validated` | `{item_id, part_number, valid, failed_count}` | After validation completes |
| `job.created` | `{job_id, definition_name, trigger, item_id}` | Job auto-triggered or manually created |
| `job.claimed` | `{job_id, runner_id, runner}` | Runner claims a job |
| `job.progress` | `{job_id, progress, message}` | Runner reports progress |
| `job.completed` | `{job_id, runner_id}` | Job finishes successfully |
| `job.failed` | `{job_id, runner_id, error}` | Job fails |
| `job.cancelled` | `{job_id, cancelled_by}` | Job cancelled by user |
---
## 10. Cross-Item Edges
For assembly constraints that reference geometry in child parts (e.g. a mate constraint between two parts), use the `dag_cross_edges` table. These edges bridge the BOM DAG and the feature DAG.
Cross-item edges are **not** included in the standard `PUT /dag` sync. They will be managed through a dedicated endpoint in a future iteration once the assembly constraint model in Create/silo-mod is finalized.
For now, the DAG sync covers intra-item dependencies only. Assembly-level interference detection uses the BOM DAG (`relationships` table) combined with per-item feature DAGs.

View File

@@ -1,13 +1,15 @@
# Silo Gap Analysis and Revision Control Roadmap
# Silo Gap Analysis
**Date:** 2026-02-08
**Date:** 2026-02-13
**Status:** Analysis Complete (Updated)
---
## Executive Summary
This document analyzes the current state of the Silo project against its specification, identifies documentation and feature gaps, and outlines a roadmap for enhanced revision control capabilities.
This document analyzes the current state of the Silo project against its specification and against SOLIDWORKS PDM (the industry-leading product data management solution). It identifies documentation gaps, feature gaps, and outlines a roadmap for enhanced revision control capabilities.
See [ROADMAP.md](ROADMAP.md) for the platform roadmap and dependency tier structure.
---
@@ -25,7 +27,7 @@ This document analyzes the current state of the Silo project against its specifi
| `docs/AUTH.md` | Authentication system design | Current |
| `docs/AUTH_USER_GUIDE.md` | User guide for login, tokens, and roles | Current |
| `docs/GAP_ANALYSIS.md` | Revision control roadmap | Current |
| `ROADMAP.md` | Feature roadmap and SOLIDWORKS PDM comparison | Current |
| `docs/ROADMAP.md` | Platform roadmap and dependency tiers | Current |
| `frontend-spec.md` | React SPA frontend specification | Current |
### 1.2 Documentation Gaps (Priority Order)
@@ -450,3 +452,163 @@ GET /api/releases/{name} # Get release details
POST /api/releases/{name}/items # Add items to release
GET /api/items/{pn}/thumbnail/{rev} # Get thumbnail
```
---
## Appendix C: SOLIDWORKS PDM Comparison
This section compares Silo's capabilities against SOLIDWORKS PDM features. Gaps are categorized by priority and implementation complexity.
**Legend:** Silo Status = Full / Partial / None | Priority = Critical / High / Medium / Low | Complexity = Simple / Moderate / Complex
### C.1 Version Control & Revision Management
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Check-in/check-out | Full pessimistic locking | None | High | Moderate |
| Version history | Complete with branching | Full (linear) | - | - |
| Revision labels | A, B, C or custom schemes | Full (custom labels) | - | - |
| Rollback/restore | Full | Full | - | - |
| Compare revisions | Visual + metadata diff | Metadata diff only | Medium | Complex |
| Get Latest Revision | One-click retrieval | Partial (API only) | Medium | Simple |
Silo lacks pessimistic locking (check-out), which is critical for multi-user CAD environments where file merging is impractical. Visual diff comparison would require FreeCAD integration for CAD file visualization.
### C.2 Workflow Management
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Custom workflows | Full visual designer | None | Critical | Complex |
| State transitions | Configurable with permissions | Basic (status field only) | Critical | Complex |
| Parallel approvals | Multiple approvers required | None | High | Complex |
| Automatic transitions | Timer/condition-based | None | Medium | Moderate |
| Email notifications | On state change | None | High | Moderate |
| ECO process | Built-in change management | None | High | Complex |
| Child state conditions | Block parent if children invalid | None | Medium | Moderate |
Workflow management is the largest functional gap. SOLIDWORKS PDM offers sophisticated state machines with parallel approvals, automatic transitions, and deep integration with engineering change processes. Silo currently has only a simple status field (draft/review/released/obsolete) with no transition rules or approval processes.
### C.3 User Management & Security
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| User authentication | Windows AD, LDAP | Full (local, LDAP, OIDC) | - | - |
| Role-based permissions | Granular per folder/state | Partial (3-tier role model) | Medium | Moderate |
| Group management | Full | None | Medium | Moderate |
| Folder permissions | Read/write/delete per folder | None | Medium | Moderate |
| State permissions | Actions allowed per state | None | High | Moderate |
| Audit trail | Complete action logging | Full | - | - |
| Private files | Pre-check-in visibility control | None | Low | Simple |
Authentication is implemented with three backends (local, LDAP/FreeIPA, OIDC/Keycloak) and a 3-tier role model (admin > editor > viewer). Audit logging captures user actions. Remaining gaps: group management, folder-level permissions, and state-based permission rules.
### C.4 Search & Discovery
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Metadata search | Full with custom cards | Partial (API query params + fuzzy) | High | Moderate |
| Full-text content search | iFilters for Office, CAD | None | Medium | Complex |
| Quick search | Toolbar with history | Partial (fuzzy search API) | Medium | Simple |
| Saved searches | User-defined favorites | None | Medium | Simple |
| Advanced operators | AND, OR, NOT, wildcards | None | Medium | Simple |
| Multi-variable search | Search across multiple fields | None | Medium | Simple |
| Where-used search | Find all assemblies using part | Full | - | - |
Silo has API-level filtering, fuzzy search, and where-used queries. Remaining gaps: saved searches, advanced search operators, and a richer search UI. Content search (searching within CAD files) is not planned for the server.
### C.5 BOM Management
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Single-level BOM | Yes | Full | - | - |
| Multi-level BOM | Indented/exploded views | Full (recursive, configurable depth) | - | - |
| BOM comparison | Between revisions | None | Medium | Moderate |
| BOM export | Excel, XML, ERP formats | Full (CSV, ODS) | - | - |
| BOM import | Bulk BOM loading | Full (CSV with upsert) | - | - |
| Calculated BOMs | Quantities rolled up | None | Medium | Moderate |
| Reference designators | Full support | Full | - | - |
| Alternate parts | Substitute tracking | Full | - | - |
Multi-level BOM retrieval (recursive CTE with configurable depth) and BOM export (CSV, ODS) are implemented. BOM import supports CSV with upsert and cycle detection. Remaining gap: BOM comparison between revisions.
### C.6 CAD Integration
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Native CAD add-in | Deep SOLIDWORKS integration | FreeCAD workbench (silo-mod) | Medium | Complex |
| Property mapping | Bi-directional sync | Planned (silo-mod) | Medium | Moderate |
| Task pane | Embedded in CAD UI | Auth dock panel (silo-mod) | Medium | Complex |
| Lightweight components | Handle without full load | N/A | - | - |
| Drawing/model linking | Automatic association | Manual | Medium | Moderate |
| Multi-CAD support | Third-party formats | FreeCAD only | Low | - |
CAD integration is maintained in separate repositories ([silo-mod](https://git.kindred-systems.com/kindred/silo-mod), [silo-calc](https://git.kindred-systems.com/kindred/silo-calc)). The Silo server provides the REST API endpoints consumed by those clients.
### C.7 External Integrations
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| ERP integration | SAP, Dynamics, etc. | Partial (Odoo stubs) | Medium | Complex |
| API access | Full COM/REST API | Full REST API (78 endpoints) | - | - |
| Dispatch scripts | Automation without coding | None | Medium | Moderate |
| Task scheduler | Background processing | None | Medium | Moderate |
| Email system | SMTP integration | None | High | Simple |
| Web portal | Browser access | Full (React SPA + auth) | - | - |
Silo has a comprehensive REST API (78 endpoints) and a full web UI with authentication. Odoo ERP integration has config/sync-log scaffolding but push/pull operations are stubs. Remaining gaps: email notifications, task scheduler, dispatch automation.
### C.8 Reporting & Analytics
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Standard reports | Inventory, usage, activity | None | Medium | Moderate |
| Custom reports | User-defined queries | None | Medium | Moderate |
| Dashboard | Visual KPIs | None | Low | Moderate |
| Export formats | PDF, Excel, CSV | CSV and ODS | Medium | Simple |
Reporting capabilities are absent. Basic reports (item counts, revision activity, where-used) would provide immediate value.
### C.9 File Handling
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| File versioning | Automatic | Full (MinIO) | - | - |
| File preview | Thumbnails, 3D preview | None | Medium | Complex |
| File conversion | PDF, DXF generation | None | Medium | Complex |
| Replication | Multi-site sync | None | Low | Complex |
| File copy with refs | Copy tree with references | None | Medium | Moderate |
File storage works well. Thumbnail generation and file preview would significantly improve the web UI experience. Automatic conversion to PDF/DXF is valuable for sharing with non-CAD users.
---
## Appendix D: Feature Comparison Matrix
| Category | Feature | SW PDM Standard | SW PDM Pro | Silo Current | Silo Planned |
|----------|---------|-----------------|------------|--------------|--------------|
| **Version Control** | Check-in/out | Yes | Yes | No | Tier 1 |
| | Version history | Yes | Yes | Yes | - |
| | Rollback | Yes | Yes | Yes | - |
| | Revision labels/status | Yes | Yes | Yes | - |
| | Revision comparison | Yes | Yes | Yes (metadata) | - |
| **Workflow** | Custom workflows | Limited | Yes | No | Tier 4 |
| | Parallel approval | No | Yes | No | Tier 4 |
| | Notifications | No | Yes | No | Tier 1 |
| **Security** | User auth | Windows | Windows/LDAP | Yes (local, LDAP, OIDC) | - |
| | Permissions | Basic | Granular | Partial (role-based) | Tier 4 |
| | Audit trail | Basic | Full | Yes | - |
| **Search** | Metadata search | Yes | Yes | Partial (API + fuzzy) | Tier 0 |
| | Content search | No | Yes | No | Tier 2 |
| | Where-used | Yes | Yes | Yes | - |
| **BOM** | Single-level | Yes | Yes | Yes | - |
| | Multi-level | Yes | Yes | Yes (recursive) | - |
| | BOM export | Yes | Yes | Yes (CSV, ODS) | - |
| **Data** | CSV import/export | Yes | Yes | Yes | - |
| | ODS import/export | No | No | Yes | - |
| | Project management | Yes | Yes | Yes | - |
| **Integration** | API | Limited | Full | Full REST (78) | - |
| | ERP connectors | No | Yes | Partial (Odoo stubs) | Tier 6 |
| | Web access | No | Yes | Yes (React SPA + auth) | - |
| **Files** | Versioning | Yes | Yes | Yes | - |
| | Preview | Yes | Yes | No | Tier 2 |
| | Multi-site | No | Yes | No | Not Planned |

View File

@@ -1,40 +1,288 @@
# Silo Roadmap
# Silo Platform Roadmap
**Version:** 1.1
**Date:** February 2026
**Purpose:** Project inventory, SOLIDWORKS PDM gap analysis, and development roadmap
**Version:** 2.0
**Date:** February 2026
Silo is the server component of the Kindred ecosystem. Its core function is storing and version-controlling engineering data (parts, assemblies, BOMs). This roadmap describes the expansion of Silo from a PDM server into a modular platform -- comparable to how Gitea/GitHub extend Git hosting with Actions, Wikis, Packages, and webhooks.
For a detailed comparison against SOLIDWORKS PDM, see [GAP_ANALYSIS.md](GAP_ANALYSIS.md).
---
## Table of Contents
## Guiding Principles
1. [Executive Summary](#executive-summary)
2. [Current Project Inventory](#current-project-inventory)
3. [SOLIDWORKS PDM Gap Analysis](#solidworks-pdm-gap-analysis)
4. [Feature Roadmap](#feature-roadmap)
5. [Implementation Phases](#implementation-phases)
- **Modular architecture.** Every capability beyond core PDM is a module. Modules register against a central API endpoint registry and declare their menu entries, views, dependencies, and routes via a module manifest.
- **Odoo-aligned UX.** The web UI follows Odoo's navigation patterns: a top-level app launcher grid, breadcrumb navigation (`Module > List > Record > Sub-view`), and standard view types (list, form, kanban, calendar, pivot). This alignment provides a familiar experience for shops already using Odoo as their ERP, and a clean integration path for those who adopt it later.
- **Open by default.** Silo and all modules are open-source. Enterprise customers can fork, extend, and self-host. Developer tools for building and distributing custom Create forks are available to everyone, not just Kindred.
- **Odoo as reference ERP.** For shops on Odoo, a bridge module syncs Silo data to Odoo models (`mrp.bom`, `mrp.production`, `quality.check`, etc.). For shops on other ERPs, the open API serves as a documented integration surface. Silo's web UI is fully self-sufficient with no ERP dependency required.
---
## Executive Summary
## Foundational Contracts
Silo is an R&D-oriented item database and part management system. It provides configurable part number generation, revision tracking, BOM management, and file versioning through MinIO storage. CAD integration (FreeCAD workbench, LibreOffice Calc extension) is maintained in separate repositories ([silo-mod](https://git.kindred-systems.com/kindred/silo-mod), [silo-calc](https://git.kindred-systems.com/kindred/silo-calc)).
### The .kc File Format
This document compares Silo's current capabilities against SOLIDWORKS PDM—the industry-leading product data management solution—to identify gaps and prioritize future development.
Silo introduces the `.kc` file format as an enhanced superset of FreeCAD's `.fcstd`. Both are ZIP bundles. A `.kc` file contains everything an `.fcstd` does, plus a `silo/` directory with platform metadata.
### Key Differentiators
#### Standard FCStd contents (preserved as-is)
| Aspect | Silo | SOLIDWORKS PDM |
|--------|------|----------------|
| **Target CAD** | FreeCAD / Kindred Create (open source) | SOLIDWORKS (proprietary) |
| **Part Numbering** | Schema-as-configuration (YAML) | Fixed format with some customization |
| **Licensing** | Open source / Kindred Proprietary | Commercial ($3,000-$10,000+ per seat) |
| **Storage** | PostgreSQL + MinIO (S3-compatible) | SQL Server + File Archive |
| **Philosophy** | R&D-oriented, lightweight | Enterprise-grade, comprehensive |
- `Document.xml`, `GuiDocument.xml`
- BREP geometry files (`.brp`)
- `thumbnails/`
#### Added .kc entries
| Path | Purpose |
|------|---------|
| `silo/manifest.json` | Silo instance origin, part UUID, revision hash, .kc schema version |
| `silo/metadata.json` | Custom schema field values, tags, lifecycle state |
| `silo/history.json` | Local revision log (lightweight; full history is server-side) |
| `silo/approvals.json` | ECO/approval state snapshot |
| `silo/dependencies.json` | Assembly link references by Silo UUID (not filepath) |
| `silo/macros/` | Embedded macro references or inline scripts bound to this part |
| `silo/inspection/` | GD&T annotations, tolerance data, CMM linkage metadata |
| `silo/thumbnails/` | Silo-generated renderings (separate from FreeCAD's built-in thumbnail) |
#### Interoperability
- **FCStd -> Silo:** On import, the `silo/` directory is generated with defaults. A UUID is assigned and the user is prompted for schema fields.
- **Silo -> FCStd:** On export, the `silo/` directory is stripped. The remaining contents are a valid `.fcstd`.
- **Round-trip safety:** FreeCAD ignores the `silo/` directory on save, so there is no risk of FreeCAD corrupting Silo metadata.
- **Schema versioning:** `silo/manifest.json` carries a format version for forward-compatible migrations.
### Module Manifest
Each module ships a manifest declaring its integration surface:
```
id, name, version, description
dependencies (other module IDs)
menu_entries (app launcher icon, label, route)
view_declarations (list, form, kanban, etc.)
api_routes (REST endpoints the module registers)
hooks (events the module listens to or emits)
permissions (required roles/scopes)
```
The exact format (JSON, TOML, or Python-based a la Odoo's `__manifest__.py`) is TBD. The contract is: a module is anything that provides a valid manifest and registers against the endpoint registry.
### Web UI Shell
The Silo web application provides the chrome that all modules render within.
- **App launcher:** Top-level grid of installed module icons. Driven by the API endpoint registry -- only enabled modules appear. Disabled modules show greyed with an "Enable" action for discoverability.
- **Breadcrumbs:** Every view follows `Module > List > Record > Sub-view`. Consistent across all modules.
- **View types:** List, form, kanban, calendar, pivot/reporting. Modules declare supported views in their manifest.
- **Schema-driven forms:** The user-customizable schema engine maps directly to form views, enabling end-users to define part metadata fields through the web UI without code changes.
---
## Current Project Inventory
## Dependency Tiers
Modules are organized into tiers based on what they depend on. Lower tiers must be stable before higher tiers are built.
### Tier 0 -- Foundation
Everything depends on these. They define what Silo *is*.
| Component | Description | Status |
|-----------|-------------|--------|
| **Core Silo** | Part/assembly storage, version control, auth, base REST API | Complete |
| **.kc Format Spec** | File format contract between Create and Silo | Not Started |
| **API Endpoint Registry** | Module discovery, dynamic UI rendering, health checks | Not Started |
| **Web UI Shell** | App launcher, breadcrumbs, view framework, module rendering | Partial |
| **Python Scripting Engine** | Server-side hook execution, module extension point | Not Started |
| **Job Queue Infrastructure** | Redis/NATS shared async service for all compute modules | Not Started |
### Tier 1 -- Core Services
Broad downstream dependencies. These should be built early because retrofitting is painful.
| Module | Description | Depends On | Status |
|--------|-------------|------------|--------|
| **Headless Create** | API-driven FreeCAD instance for file manipulation, geometry queries, format conversion, rendering | Core Silo, Job Queue | Not Started |
| **Notifications & Subscriptions** | Per-part watch lists, lifecycle event hooks, webhook delivery | Core Silo, Registry | Not Started |
| **Audit Trail / Compliance** | ITAR, ISO 9001, AS9100 traceability; module-level event journaling | Core Silo | Partial |
### Tier 2 -- File Intelligence & Collaboration
High-visibility features. Mostly low-hanging fruit once Tier 1 is solid.
| Module | Description | Depends On | Status |
|--------|-------------|------------|--------|
| **Intelligent FCStd Diffing** | XML-based structural diff of .kc bundles | Headless Create | Not Started |
| **Thumbnail Generation** | Auto-rendered part/assembly previews | Headless Create | Not Started |
| **Macro Store** | Shared macro library across Create instances | Core Silo, Registry | Not Started |
| **Theme & Addon Manager** | Centralized distribution of UI themes and workbench addons | Core Silo, Registry | Not Started |
| **User-Customizable Schemas** | End-user defined part/form metadata via web UI | Core Silo, Scripting Engine | Not Started |
### Tier 3 -- Compute
Heavy async workloads. All route through the shared job queue.
| Module | Description | Depends On | Status |
|--------|-------------|------------|--------|
| **Batch Jobs (CPU/GPU)** | FEA, CFD, rendering, bulk export | Job Queue, Headless Create | Not Started |
| **AI Broker** | LLM tasks (Ollama), GNN constraint optimization, appearance AI | Job Queue | Not Started |
| **Reporting & Analytics** | Part reuse, revision frequency, compute usage dashboards, cost roll-ups | Audit Trail, Core Silo | Not Started |
### Tier 4 -- Engineering Workflow
Process modules that formalize how engineering work moves through an organization.
| Module | Description | Depends On | Status |
|--------|-------------|------------|--------|
| **Approval / ECO Workflow** | Engineering change orders, multi-stage review gates, digital signatures | Notifications, Audit Trail, Schemas | Not Started |
| **Shop Floor Drawing Distribution** | Controlled push-to-production drawings; web-based appliance displays on the floor | Headless Create, Approval Workflow | Not Started |
| **Import/Export Bridge** | STEP, IGES, 3MF connectors; SOLIDWORKS migration tooling; ERP adapters | Headless Create | Not Started |
| **Multi-tenant / Org Management** | Org boundaries, role-based permissioning, storage quotas | Core Auth, Audit Trail | Not Started |
### Tier 5 -- Manufacturing & Quality
Deep domain modules. Heavy spec work required independent of software dependencies.
| Module | Description | Depends On | Status |
|--------|-------------|------------|--------|
| **MES Module** | Manufacturing execution -- internal module or bridge to external MES | Approval Workflow, Schemas, Shop Floor Drawings | Not Started |
| **Quality / Tolerance Stackup** | Inspection data ingestion, CMM device linking, statistical tolerance analysis, material mapping | Schemas, Import Bridge | Not Started |
| **Inspection Plan Generator** | Auto-generate CMM programs or inspection checklists from GD&T drawings | Headless Create, Quality Module | Not Started |
| **BIM Inventory / Receiving** | Live facility model with real-time inventory location, explorable in a custom BIM-MES workbench in Create | Custom BIM-MES Workbench, Schemas, Notifications | Not Started |
### Tier 6 -- Platform & Ecosystem
Modules that serve the broader community and long-horizon use cases.
| Module | Description | Depends On | Status |
|--------|-------------|------------|--------|
| **Developer Tools** | Managed Gitea instance for in-house Create fork development; CI/CD to build and distribute fork updates to configured clients | Tier 0-1 stability | Not Started |
| **Digital Twin Sync** | Live sensor data mapped onto BIM/assembly models; operational monitoring | BIM Inventory, Reporting | Not Started |
| **ERP Adapters (Odoo, SAP, etc.)** | Bidirectional sync of parts, BOMs, ECOs, production orders to external ERP | Import/Export Bridge, MES, Schemas | Partial (Odoo stubs) |
---
## Near-Term Priorities
These are the concrete tasks that map to Tier 0 completion and the first steps into Tier 1. They replace the older Phase 1-6 calendar-based timelines.
### Tier 0 Completion
Complete MVP and stabilize core functionality.
| Task | Description | Status |
|------|-------------|--------|
| Unit test suite | Core API, database, partnum, file, CSV/ODS handler tests | Partial (~40%) |
| Date segment type | Implement `date` segment with strftime-style formatting | Not Started |
| Part number validation | Validate format against schema on creation | Not Started |
| Location CRUD API | Expose location hierarchy via REST | Not Started |
| Inventory API | Expose inventory operations via REST | Not Started |
**Success metrics:**
- All existing tests pass
- File upload/download works end-to-end
- FreeCAD users can checkout, modify, commit parts
### Multi-User Enablement
Enable team collaboration (feeds into Tier 1 and Tier 4).
| Task | Description | Status |
|------|-------------|--------|
| Check-out locking | Pessimistic locks with timeout | Not Started |
| User/group management | Create, assign, manage users and groups | Not Started |
| Folder permissions | Read/write/delete per folder hierarchy | Not Started |
**Success metrics:**
- 5+ concurrent users supported
- No data corruption under concurrent access
- Audit log captures all modifications
### Workflow Engine
Implement engineering change processes (Tier 4: Approval/ECO Workflow).
| Task | Description | Status |
|------|-------------|--------|
| Workflow designer | YAML-defined state machines | Not Started |
| State transitions | Configurable transition rules with permissions | Not Started |
| Approval workflows | Single and parallel approver gates | Not Started |
| Email notifications | SMTP integration for alerts on state changes | Not Started |
**Success metrics:**
- Engineering change process completable in Silo
- Email notifications delivered reliably
- Workflow state visible in web UI
### Search & Discovery
Improve findability and navigation (Tier 0 Web UI Shell).
| Task | Description | Status |
|------|-------------|--------|
| Advanced search UI | Web interface with filters and operators | Not Started |
| Saved searches | User-defined query favorites | Not Started |
**Success metrics:**
- Search returns results in <2 seconds
- Where-used queries complete in <5 seconds
---
## Gap Summary
For full SOLIDWORKS PDM comparison tables, see [GAP_ANALYSIS.md Appendix C](GAP_ANALYSIS.md#appendix-c-solidworks-pdm-comparison).
### Completed (Previously Critical/High)
1. ~~User authentication~~ -- local, LDAP, OIDC
2. ~~Role-based permissions~~ -- 3-tier role model (admin/editor/viewer)
3. ~~Audit trail~~ -- audit_log table with completeness scoring
4. ~~Where-used search~~ -- reverse parent lookup API
5. ~~Multi-level BOM API~~ -- recursive expansion with configurable depth
6. ~~BOM export~~ -- CSV and ODS formats
### Critical Gaps (Required for Team Use)
1. **Workflow engine** -- state machines with transitions and approvals
2. **Check-out locking** -- pessimistic locking for CAD files
### High Priority Gaps (Significant Value)
1. **Email notifications** -- alert users on state changes
2. **Web UI search** -- advanced search interface with saved searches
3. **Folder/state permissions** -- granular access control beyond role model
### Medium Priority Gaps (Nice to Have)
1. **Saved searches** -- frequently used queries
2. **File preview/thumbnails** -- visual browsing
3. **Reporting** -- activity and inventory reports
4. **Scheduled tasks** -- background automation
5. **BOM comparison** -- revision diff for assemblies
---
## Priority Notes
- **Headless Create** is the single highest-leverage Tier 1 item. It unblocks diffing, thumbnails, batch export, drawing distribution, and inspection plan generation.
- **Audit Trail** is unglamorous but critical to build early. Retrofitting compliance logging after modules ship is expensive and error-prone.
- **Tier 2** delivers visible, demo-able value quickly -- diffing, thumbnails, and the macro store are features users immediately understand.
- **Tiers 5-6** carry heavy domain complexity. They need detailed specification and industry consultation well before implementation begins.
- The **.kc format** and **module manifest** are the two foundational contracts. Getting these right determines how cleanly everything above them composes.
---
## Open Questions
1. **Module manifest format** -- JSON, TOML, or Python-based? Tradeoffs between simplicity and expressiveness.
2. **.kc thumbnail policy** -- Single canonical thumbnail vs. multi-view renders. Impacts file size and generation cost.
3. **Job queue technology** -- Redis Streams vs. NATS. Redis is already in the stack; NATS offers better pub/sub semantics for event-driven modules.
4. **Headless Create deployment** -- Sidecar container per Silo instance, or pool of workers behind the job queue?
5. **BIM-MES workbench scope** -- How much of FreeCAD BIM is reusable vs. needs to be purpose-built for inventory/facility modeling?
6. **Offline .kc workflow** -- How much of the `silo/` metadata is authoritative when disconnected? Reconciliation strategy on reconnect.
---
## Appendix A: Current Project Inventory
### Implemented Features (MVP Complete)
@@ -99,7 +347,7 @@ This document compares Silo's current capabilities against SOLIDWORKS PDM—the
- Session management (PostgreSQL-backed, 24h lifetime)
- CSRF protection (nosurf on web forms)
- Middleware: logging, CORS, recovery, request ID
- Web UI React SPA (Vite + TypeScript, Catppuccin Mocha theme)
- Web UI -- React SPA (Vite + TypeScript, Catppuccin Mocha theme)
- Fuzzy search
- Health and readiness probes
@@ -123,304 +371,19 @@ This document compares Silo's current capabilities against SOLIDWORKS PDM—the
| Part number validation | Not started | API accepts but doesn't validate format |
| Location hierarchy CRUD | Schema only | Tables exist, no API endpoints |
| Inventory tracking | Schema only | Tables exist, no API endpoints |
| Unit tests | Partial | 9 Go test files across api, db, ods, partnum, schema packages |
### Infrastructure Status
| Component | Status |
|-----------|--------|
| PostgreSQL | Running (psql.example.internal) |
| MinIO | Configured in Docker Compose |
| Silo API Server | Builds successfully |
| Docker Compose | Complete (dev and production) |
| systemd service | Unit file and env template ready |
| Deployment scripts | setup-host, deploy, init-db, setup-ipa-nginx |
| Unit tests | Partial | 11 Go test files across api, db, ods, partnum, schema packages |
---
## SOLIDWORKS PDM Gap Analysis
## Appendix B: Phase 1 Detailed Tasks
This section compares Silo's capabilities against SOLIDWORKS PDM features. Gaps are categorized by priority and implementation complexity.
### Legend
- **Silo Status:** Full / Partial / None
- **Priority:** Critical / High / Medium / Low
- **Complexity:** Simple / Moderate / Complex
---
### 1. Version Control & Revision Management
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Check-in/check-out | Full pessimistic locking | None | High | Moderate |
| Version history | Complete with branching | Full (linear) | - | - |
| Revision labels | A, B, C or custom schemes | Full (custom labels) | - | - |
| Rollback/restore | Full | Full | - | - |
| Compare revisions | Visual + metadata diff | Metadata diff only | Medium | Complex |
| Get Latest Revision | One-click retrieval | Partial (API only) | Medium | Simple |
**Gap Analysis:**
Silo lacks pessimistic locking (check-out), which is critical for multi-user CAD environments where file merging is impractical. Visual diff comparison would require FreeCAD integration for CAD file visualization.
---
### 2. Workflow Management
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Custom workflows | Full visual designer | None | Critical | Complex |
| State transitions | Configurable with permissions | Basic (status field only) | Critical | Complex |
| Parallel approvals | Multiple approvers required | None | High | Complex |
| Automatic transitions | Timer/condition-based | None | Medium | Moderate |
| Email notifications | On state change | None | High | Moderate |
| ECO process | Built-in change management | None | High | Complex |
| Child state conditions | Block parent if children invalid | None | Medium | Moderate |
**Gap Analysis:**
Workflow management is the largest functional gap. SOLIDWORKS PDM offers sophisticated state machines with parallel approvals, automatic transitions, and deep integration with engineering change processes. Silo currently has only a simple status field (draft/review/released/obsolete) with no transition rules or approval processes.
---
### 3. User Management & Security
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| User authentication | Windows AD, LDAP | Full (local, LDAP, OIDC) | - | - |
| Role-based permissions | Granular per folder/state | Partial (3-tier role model) | Medium | Moderate |
| Group management | Full | None | Medium | Moderate |
| Folder permissions | Read/write/delete per folder | None | Medium | Moderate |
| State permissions | Actions allowed per state | None | High | Moderate |
| Audit trail | Complete action logging | Full | - | - |
| Private files | Pre-check-in visibility control | None | Low | Simple |
**Gap Analysis:**
Authentication is implemented with three backends (local, LDAP/FreeIPA, OIDC/Keycloak) and a 3-tier role model (admin > editor > viewer). Audit logging captures user actions. Remaining gaps: group management, folder-level permissions, and state-based permission rules.
---
### 4. Search & Discovery
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Metadata search | Full with custom cards | Partial (API query params + fuzzy) | High | Moderate |
| Full-text content search | iFilters for Office, CAD | None | Medium | Complex |
| Quick search | Toolbar with history | Partial (fuzzy search API) | Medium | Simple |
| Saved searches | User-defined favorites | None | Medium | Simple |
| Advanced operators | AND, OR, NOT, wildcards | None | Medium | Simple |
| Multi-variable search | Search across multiple fields | None | Medium | Simple |
| Where-used search | Find all assemblies using part | Full | - | - |
**Gap Analysis:**
Silo has API-level filtering, fuzzy search, and where-used queries. Remaining gaps: saved searches, advanced search operators, and a richer search UI. Content search (searching within CAD files) is not planned for the server.
---
### 5. BOM Management
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Single-level BOM | Yes | Full | - | - |
| Multi-level BOM | Indented/exploded views | Full (recursive, configurable depth) | - | - |
| BOM comparison | Between revisions | None | Medium | Moderate |
| BOM export | Excel, XML, ERP formats | Full (CSV, ODS) | - | - |
| BOM import | Bulk BOM loading | Full (CSV with upsert) | - | - |
| Calculated BOMs | Quantities rolled up | None | Medium | Moderate |
| Reference designators | Full support | Full | - | - |
| Alternate parts | Substitute tracking | Full | - | - |
**Gap Analysis:**
Multi-level BOM retrieval (recursive CTE with configurable depth) and BOM export (CSV, ODS) are implemented. BOM import supports CSV with upsert and cycle detection. Remaining gap: BOM comparison between revisions.
---
### 6. CAD Integration
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Native CAD add-in | Deep SOLIDWORKS integration | FreeCAD workbench (silo-mod) | Medium | Complex |
| Property mapping | Bi-directional sync | Planned (silo-mod) | Medium | Moderate |
| Task pane | Embedded in CAD UI | Auth dock panel (silo-mod) | Medium | Complex |
| Lightweight components | Handle without full load | N/A | - | - |
| Drawing/model linking | Automatic association | Manual | Medium | Moderate |
| Multi-CAD support | Third-party formats | FreeCAD only | Low | - |
**Gap Analysis:**
CAD integration is maintained in separate repositories ([silo-mod](https://git.kindred-systems.com/kindred/silo-mod), [silo-calc](https://git.kindred-systems.com/kindred/silo-calc)). The Silo server provides the REST API endpoints consumed by those clients.
---
### 7. External Integrations
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| ERP integration | SAP, Dynamics, etc. | Partial (Odoo stubs) | Medium | Complex |
| API access | Full COM/REST API | Full REST API (78 endpoints) | - | - |
| Dispatch scripts | Automation without coding | None | Medium | Moderate |
| Task scheduler | Background processing | None | Medium | Moderate |
| Email system | SMTP integration | None | High | Simple |
| Web portal | Browser access | Full (React SPA + auth) | - | - |
**Gap Analysis:**
Silo has a comprehensive REST API (78 endpoints) and a full web UI with authentication. Odoo ERP integration has config/sync-log scaffolding but push/pull operations are stubs. Remaining gaps: email notifications, task scheduler, dispatch automation.
---
### 8. Reporting & Analytics
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| Standard reports | Inventory, usage, activity | None | Medium | Moderate |
| Custom reports | User-defined queries | None | Medium | Moderate |
| Dashboard | Visual KPIs | None | Low | Moderate |
| Export formats | PDF, Excel, CSV | CSV and ODS | Medium | Simple |
**Gap Analysis:**
Reporting capabilities are absent. Basic reports (item counts, revision activity, where-used) would provide immediate value.
---
### 9. File Handling
| Feature | SOLIDWORKS PDM | Silo Status | Priority | Complexity |
|---------|---------------|-------------|----------|------------|
| File versioning | Automatic | Full (MinIO) | - | - |
| File preview | Thumbnails, 3D preview | None | Medium | Complex |
| File conversion | PDF, DXF generation | None | Medium | Complex |
| Replication | Multi-site sync | None | Low | Complex |
| File copy with refs | Copy tree with references | None | Medium | Moderate |
**Gap Analysis:**
File storage works well. Thumbnail generation and file preview would significantly improve the web UI experience. Automatic conversion to PDF/DXF is valuable for sharing with non-CAD users.
---
### Gap Summary by Priority
#### Completed (Previously Critical/High)
1. ~~**User authentication**~~ - Implemented: local, LDAP, OIDC
2. ~~**Role-based permissions**~~ - Implemented: 3-tier role model (admin/editor/viewer)
3. ~~**Audit trail**~~ - Implemented: audit_log table with completeness scoring
4. ~~**Where-used search**~~ - Implemented: reverse parent lookup API
5. ~~**Multi-level BOM API**~~ - Implemented: recursive expansion with configurable depth
6. ~~**BOM export**~~ - Implemented: CSV and ODS formats
#### Critical Gaps (Required for Team Use)
1. **Workflow engine** - State machines with transitions and approvals
2. **Check-out locking** - Pessimistic locking for CAD files
#### High Priority Gaps (Significant Value)
1. **Email notifications** - Alert users on state changes
2. **Web UI search** - Advanced search interface with saved searches
3. **Folder/state permissions** - Granular access control beyond role model
#### Medium Priority Gaps (Nice to Have)
1. **Saved searches** - Frequently used queries
2. **File preview/thumbnails** - Visual browsing
3. **Reporting** - Activity and inventory reports
4. **Scheduled tasks** - Background automation
5. **BOM comparison** - Revision diff for assemblies
---
## Feature Roadmap
### Phase 1: Foundation (Current - Q2 2026)
*Complete MVP and stabilize core functionality*
| Feature | Description | Status |
|---------|-------------|--------|
| MinIO integration | File upload/download with versioning and checksums | Complete |
| Revision control | Rollback, comparison, status/labels | Complete |
| CSV import/export | Dry-run validation, template generation | Complete |
| ODS import/export | Items, BOMs, project sheets, templates | Complete |
| Project management | CRUD, many-to-many item tagging | Complete |
| Multi-level BOM | Recursive expansion, where-used, export | Complete |
| Authentication | Local, LDAP, OIDC with role-based access | Complete |
| Audit logging | Action logging, completeness scoring | Complete |
| Unit tests | Core API and database operations | Not Started |
| Date segment type | Support date-based part number segments | Not Started |
| Part number validation | Validate format on creation | Not Started |
| Location CRUD API | Expose location hierarchy via REST | Not Started |
| Inventory API | Expose inventory operations via REST | Not Started |
### Phase 2: Multi-User (Q2-Q3 2026)
*Enable team collaboration*
| Feature | Description | Status |
|---------|-------------|--------|
| LDAP authentication | Integrate with FreeIPA/Active Directory | **Complete** |
| OIDC authentication | Keycloak / OpenID Connect | **Complete** |
| Audit logging | Record all user actions with timestamps | **Complete** |
| Session management | Token-based and session-based API authentication | **Complete** |
| User/group management | Create, assign, manage users and groups | Not Started |
| Folder permissions | Read/write/delete per folder hierarchy | Not Started |
| Check-out locking | Pessimistic locks with timeout | Not Started |
### Phase 3: Workflow Engine (Q3-Q4 2026)
*Implement engineering change processes*
| Feature | Description | Complexity |
|---------|-------------|------------|
| Workflow designer | YAML-defined state machines | Complex |
| State transitions | Configurable transition rules | Complex |
| Transition permissions | Who can execute which transitions | Moderate |
| Single approvals | Basic approval workflow | Moderate |
| Parallel approvals | Multi-approver gates | Complex |
| Automatic transitions | Timer and condition-based | Complex |
| Email notifications | SMTP integration for alerts | Simple |
| Child state conditions | Block parent transitions | Moderate |
### Phase 4: Search & Discovery (Q4 2026 - Q1 2027)
*Improve findability and navigation*
| Feature | Description | Status |
|---------|-------------|--------|
| Where-used queries | Find parent assemblies | **Complete** |
| Fuzzy search | Quick search across items | **Complete** |
| Advanced search UI | Web interface with filters | Not Started |
| Search operators | AND, OR, NOT, wildcards | Not Started |
| Saved searches | User favorites | Not Started |
| Content search | Search within file content | Not Started |
### Phase 5: BOM & Reporting (Q1-Q2 2027)
*Enhanced BOM management and analytics*
| Feature | Description | Status |
|---------|-------------|--------|
| Multi-level BOM API | Recursive assembly retrieval | **Complete** |
| BOM export | CSV and ODS formats | **Complete** |
| BOM import | CSV with upsert and cycle detection | **Complete** |
| BOM comparison | Diff between revisions | Not Started |
| Standard reports | Activity, inventory, usage | Not Started |
| Custom queries | User-defined report builder | Not Started |
| Dashboard | Visual KPIs and metrics | Not Started |
### Phase 6: Advanced Features (Q2-Q4 2027)
*Enterprise capabilities*
| Feature | Description | Complexity |
|---------|-------------|------------|
| File preview | Thumbnail generation | Complex |
| File conversion | Auto-generate PDF/DXF | Complex |
| ERP integration | Adapter framework | Complex |
| Task scheduler | Background job processing | Moderate |
| Webhooks | Event notifications to external systems | Moderate |
| API rate limiting | Protect against abuse | Simple |
---
## Implementation Phases
### Phase 1 Detailed Tasks
#### 1.1 MinIO Integration -- COMPLETE
### 1.1 MinIO Integration -- COMPLETE
- [x] MinIO service configured in Docker Compose
- [x] File upload via REST API
- [x] File download via REST API (latest and by revision)
- [x] SHA256 checksums on upload
#### 1.2 Authentication & Authorization -- COMPLETE
### 1.2 Authentication & Authorization -- COMPLETE
- [x] Local authentication (bcrypt)
- [x] LDAP/FreeIPA authentication
- [x] OIDC/Keycloak authentication
@@ -430,14 +393,14 @@ File storage works well. Thumbnail generation and file preview would significant
- [x] CSRF protection (nosurf)
- [x] Audit logging (database table)
#### 1.3 Multi-level BOM & Export -- COMPLETE
### 1.3 Multi-level BOM & Export -- COMPLETE
- [x] Recursive BOM expansion with configurable depth
- [x] Where-used reverse lookup
- [x] BOM CSV export/import with cycle detection
- [x] BOM ODS export
- [x] ODS item export/import/template
#### 1.4 Unit Test Suite
### 1.4 Unit Test Suite
- [ ] Database connection and transaction tests
- [ ] Item CRUD operation tests
- [ ] Revision creation and retrieval tests
@@ -446,11 +409,11 @@ File storage works well. Thumbnail generation and file preview would significant
- [ ] CSV import/export tests
- [ ] API endpoint tests
#### 1.5 Missing Segment Types
### 1.5 Missing Segment Types
- [ ] Implement date segment type
- [ ] Add strftime-style format support
#### 1.6 Location & Inventory APIs
### 1.6 Location & Inventory APIs
- [ ] `GET /api/locations` - List locations
- [ ] `POST /api/locations` - Create location
- [ ] `GET /api/locations/{path}` - Get location
@@ -461,31 +424,7 @@ File storage works well. Thumbnail generation and file preview would significant
---
## Success Metrics
### Phase 1 (Foundation)
- All existing tests pass
- File upload/download works end-to-end
- FreeCAD users can checkout, modify, commit parts
### Phase 2 (Multi-User)
- 5+ concurrent users supported
- No data corruption under concurrent access
- Audit log captures all modifications
### Phase 3 (Workflow)
- Engineering change process completable in Silo
- Email notifications delivered reliably
- Workflow state visible in web UI
### Phase 4+ (Advanced)
- Search returns results in <2 seconds
- Where-used queries complete in <5 seconds
- BOM export matches assembly structure
---
## References
## Appendix C: References
### SOLIDWORKS PDM Documentation
- [SOLIDWORKS PDM Product Page](https://www.solidworks.com/product/solidworks-pdm)
@@ -497,40 +436,7 @@ File storage works well. Thumbnail generation and file preview would significant
- [SOLIDWORKS PDM API Getting Started](https://3dswym.3dexperience.3ds.com/wiki/solidworks-news-info/getting-started-with-the-solidworks-pdm-api-solidpractices_gBCYaM75RgORBcpSO1m_Mw)
### Silo Documentation
- [Specification](docs/SPECIFICATION.md)
- [Development Status](docs/STATUS.md)
- [Deployment Guide](docs/DEPLOYMENT.md)
- [Gap Analysis](docs/GAP_ANALYSIS.md)
---
## Appendix: Feature Comparison Matrix
| Category | Feature | SW PDM Standard | SW PDM Pro | Silo Current | Silo Planned |
|----------|---------|-----------------|------------|--------------|--------------|
| **Version Control** | Check-in/out | Yes | Yes | No | Phase 2 |
| | Version history | Yes | Yes | Yes | - |
| | Rollback | Yes | Yes | Yes | - |
| | Revision labels/status | Yes | Yes | Yes | - |
| | Revision comparison | Yes | Yes | Yes (metadata) | - |
| **Workflow** | Custom workflows | Limited | Yes | No | Phase 3 |
| | Parallel approval | No | Yes | No | Phase 3 |
| | Notifications | No | Yes | No | Phase 3 |
| **Security** | User auth | Windows | Windows/LDAP | Yes (local, LDAP, OIDC) | - |
| | Permissions | Basic | Granular | Partial (role-based) | Phase 2 |
| | Audit trail | Basic | Full | Yes | - |
| **Search** | Metadata search | Yes | Yes | Partial (API + fuzzy) | Phase 4 |
| | Content search | No | Yes | No | Phase 4 |
| | Where-used | Yes | Yes | Yes | - |
| **BOM** | Single-level | Yes | Yes | Yes | - |
| | Multi-level | Yes | Yes | Yes (recursive) | - |
| | BOM export | Yes | Yes | Yes (CSV, ODS) | - |
| **Data** | CSV import/export | Yes | Yes | Yes | - |
| | ODS import/export | No | No | Yes | - |
| | Project management | Yes | Yes | Yes | - |
| **Integration** | API | Limited | Full | Full REST (75) | - |
| | ERP connectors | No | Yes | Partial (Odoo stubs) | Phase 6 |
| | Web access | No | Yes | Yes (React SPA + auth) | - |
| **Files** | Versioning | Yes | Yes | Yes | - |
| | Preview | Yes | Yes | No | Phase 6 |
| | Multi-site | No | Yes | No | Not Planned |
- [Specification](SPECIFICATION.md)
- [Development Status](STATUS.md)
- [Deployment Guide](DEPLOYMENT.md)
- [Gap Analysis](GAP_ANALYSIS.md)

View File

@@ -0,0 +1,515 @@
# Silo Style Guide
> Living reference for the Silo web UI. All modules must follow these conventions to maintain visual consistency across the platform.
---
## Color System
Silo uses the [Catppuccin Mocha](https://github.com/catppuccin/catppuccin) palette exclusively. All colors are referenced via CSS custom properties defined at `:root`.
### Palette
```
--ctp-rosewater: #f5e0dc
--ctp-flamingo: #f2cdcd
--ctp-pink: #f5c2e7
--ctp-mauve: #cba6f7
--ctp-red: #f38ba8
--ctp-maroon: #eba0ac
--ctp-peach: #fab387
--ctp-yellow: #f9e2af
--ctp-green: #a6e3a1
--ctp-teal: #94e2d5
--ctp-sky: #89dceb
--ctp-sapphire: #74c7ec
--ctp-blue: #89b4fa
--ctp-lavender: #b4befe
--ctp-text: #cdd6f4
--ctp-subtext1: #bac2de
--ctp-subtext0: #a6adc8
--ctp-overlay2: #9399b2
--ctp-overlay1: #7f849c
--ctp-overlay0: #6c7086
--ctp-surface2: #585b70
--ctp-surface1: #45475a
--ctp-surface0: #313244
--ctp-base: #1e1e2e
--ctp-mantle: #181825
--ctp-crust: #11111b
```
### Semantic Roles
| Role | Token | Usage |
|------|-------|-------|
| Page background | `--ctp-base` | Main content area |
| Panel background | `--ctp-mantle` | Sidebars, detail panes, headers |
| Inset/input background | `--ctp-crust` | Form inputs, code blocks, drop zones |
| Primary accent | `--ctp-mauve` | Primary buttons, active states, links, selection highlights |
| Secondary accent | `--ctp-blue` | Informational highlights, secondary actions |
| Success | `--ctp-green` | Confirmations, positive status |
| Warning | `--ctp-yellow` | Caution states, pending actions |
| Danger | `--ctp-red` | Destructive actions, errors, required indicators |
| Informational | `--ctp-teal` | Auto-generated metadata, system-assigned values |
| Body text | `--ctp-text` | Primary content |
| Secondary text | `--ctp-subtext1` | Descriptions, timestamps |
| Muted text | `--ctp-overlay1` | Placeholders, disabled states |
| Borders | `--ctp-surface0` | Dividers, panel edges |
| Hover borders | `--ctp-surface1` | Interactive element borders, row separators |
| Focus ring | `rgba(203, 166, 247, 0.25)` | `box-shadow` on focused inputs (mauve at 25%) |
### Accent Usage for Data Types
| Data type | Color | Token |
|-----------|-------|-------|
| Assembly | `--ctp-mauve` | Badge, icon tint |
| Part | `--ctp-green` | Badge, icon tint |
| Document | `--ctp-blue` | Badge, icon tint |
| Purchased | `--ctp-peach` | Badge, icon tint |
| Phantom | `--ctp-overlay1` | Badge, icon tint |
These mappings are used anywhere item types appear: list badges, detail pane headers, BOM entries, tree views.
---
## Typography
### Scale
| Role | Size | Weight | Token/Color | Transform |
|------|------|--------|-------------|-----------|
| Page title | 1.1rem | 600 | `--ctp-text` | None |
| Section header | 11px | 600 | `--ctp-overlay0` | Uppercase, `letter-spacing: 0.06em` |
| Form label | 11px | 600 | `--ctp-overlay1` | Uppercase, `letter-spacing: 0.05em` |
| Body text | 13px | 400 | `--ctp-text` | None |
| Table cell | 12px | 400 | `--ctp-text` | None |
| Caption / metadata | 11px | 400 | `--ctp-subtext0` | None |
| Badge text | 10px | 600 | Varies | Uppercase |
| Breadcrumb segment | 13px | 500 | `--ctp-subtext1` | None |
| Breadcrumb active | 13px | 600 | `--ctp-text` | None |
### Font Stack
```css
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
```
No external font dependencies. System fonts ensure fast rendering and native feel across platforms.
### Rules
- Never use font sizes below 10px.
- Use `font-weight: 600` for emphasis instead of bold (700). Reserve 700 for page titles only when extra weight is needed.
- `text-transform: uppercase` is reserved for section headers, form labels, and badges. Never uppercase body text or descriptions.
---
## Spacing
Base unit: **4px**. All spacing values are multiples of 4.
| Token | Value | Usage |
|-------|-------|-------|
| `xs` | 4px (0.25rem) | Tight gaps: icon-to-label, tag internal padding |
| `sm` | 8px (0.5rem) | Compact spacing: between related fields, badge padding |
| `md` | 12px (0.75rem) | Standard: form group gaps, sidebar section padding |
| `lg` | 16px (1rem) | Section separation, card padding |
| `xl` | 24px (1.5rem) | Page-level padding, major section breaks |
| `2xl` | 32px (2rem) | Page horizontal padding |
### Application
- **Page padding:** `1.5rem 2rem` (24px vertical, 32px horizontal)
- **Sidebar section padding:** `1rem 1.25rem`
- **Form grid gap:** `1.25rem 1.5rem` (row gap × column gap)
- **Table row height:** 36px minimum (padding included)
- **Table cell padding:** `0.4rem 0.75rem`
---
## Layout
### Page Structure
Every module page follows the same shell:
```
┌─────────────────────────────────────────────────┐
│ Top Nav (52px) │
├──────────┬──────────────────────────────────────┤
│ App Menu │ Page Header (58px) │
│ (icons) ├──────────────────────┬───────────────┤
│ │ Content Area │ Detail Pane │
│ │ │ (360px) │
│ │ │ │
│ │ │ │
└──────────┴──────────────────────┴───────────────┘
```
- **Top nav:** `52px` height, `--ctp-mantle` background, `1px solid --ctp-surface0` bottom border.
- **App menu sidebar:** Icon strip on the left. Module icons, tooltips on hover. Active module highlighted with `--ctp-mauve` indicator.
- **Page header:** `58px` height, `--ctp-mantle` background. Contains page title (with module icon), action buttons right-aligned.
- **Content area:** `--ctp-base` background. Scrollable. Contains list views, kanban boards, or other primary content.
- **Detail pane:** `360px` fixed width, `--ctp-mantle` background, `1px solid --ctp-surface0` left border. Appears on record selection.
### Grid Patterns
**Two-column form:**
```css
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.25rem 1.5rem;
max-width: 800px;
```
**List + detail:**
```css
display: grid;
grid-template-columns: 1fr 360px;
min-height: calc(100vh - 52px - 58px);
```
### Breakpoints
Not currently required. Silo targets desktop browsers on engineering workstations. If mobile support is added later, breakpoints will be defined at `768px` and `1024px`.
---
## Components
### Buttons
Four tiers. All buttons share a base style:
```css
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.4rem 0.85rem;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s;
```
| Tier | Name | Background | Border | Text | Hover |
|------|------|-----------|--------|------|-------|
| Primary | `.btn-primary` | `--ctp-mauve` | `--ctp-mauve` | `--ctp-crust` | `--ctp-lavender` bg + border |
| Secondary | `.btn` (default) | `--ctp-surface0` | `--ctp-surface1` | `--ctp-text` | `--ctp-surface1` bg, `--ctp-overlay0` border |
| Ghost | `.btn-ghost` | transparent | transparent | `--ctp-subtext0` | `--ctp-surface0` bg, `--ctp-text` text |
| Danger | `.btn-danger` | transparent | `--ctp-surface1` | `--ctp-red` | `rgba(243, 139, 168, 0.1)` bg, `--ctp-red` border |
Primary is used once per visible context (the main action). All other actions use secondary or ghost. Danger is only for destructive actions and always requires confirmation.
### Badges
Used for type indicators, status labels, and tags.
```css
display: inline-flex;
align-items: center;
padding: 0.15rem 0.5rem;
border-radius: 4px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.03em;
```
Badges use a translucent background derived from their accent color:
```css
/* Example: assembly badge */
background: rgba(203, 166, 247, 0.15); /* --ctp-mauve at 15% */
color: var(--ctp-mauve);
```
Standard badge colors follow the [accent usage table](#accent-usage-for-data-types). Status badges:
| Status | Color |
|--------|-------|
| Active / Released | `--ctp-green` |
| Draft / In Progress | `--ctp-blue` |
| Review / Pending | `--ctp-yellow` |
| Obsolete / Rejected | `--ctp-red` |
| Locked | `--ctp-overlay1` |
### Form Inputs
All inputs share a base style:
```css
background: var(--ctp-crust);
border: 1px solid var(--ctp-surface1);
border-radius: 6px;
padding: 0.45rem 0.65rem;
font-size: 12px;
color: var(--ctp-text);
transition: border-color 0.15s;
```
| State | Border | Shadow |
|-------|--------|--------|
| Default | `--ctp-surface1` | None |
| Hover | `--ctp-overlay0` | None |
| Focus | `--ctp-mauve` | `0 0 0 0.2rem rgba(203, 166, 247, 0.25)` |
| Error | `--ctp-red` | `0 0 0 0.2rem rgba(243, 139, 168, 0.15)` |
| Disabled | `--ctp-surface0` | None, `opacity: 0.5` |
Placeholder text: `--ctp-overlay0`. Labels sit above inputs (never inline or floating).
### Tag Input
Used for multi-value fields (projects, tags):
```css
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
padding: 0.35rem 0.5rem;
background: var(--ctp-crust);
border: 1px solid var(--ctp-surface1);
border-radius: 6px;
min-height: 36px;
```
Individual tags use the badge pattern: `rgba(accent, 0.15)` background with accent text. Remove button (×) at `opacity: 0.6`, `1.0` on hover.
### Tables
```css
width: 100%;
border-collapse: collapse;
font-size: 12px;
```
| Element | Style |
|---------|-------|
| Header row | `background: --ctp-mantle`, `font-size: 11px`, uppercase, `--ctp-overlay1` text |
| Body row | `border-bottom: 1px solid --ctp-surface0` |
| Row hover | `background: --ctp-surface0` |
| Row selected | `background: rgba(203, 166, 247, 0.08)` |
| Cell padding | `0.4rem 0.75rem` |
| Text columns | Left-aligned |
| Number columns | Right-aligned |
| Date columns | Right-aligned |
| Action columns | Center-aligned |
Row actions use icon buttons (not text links). Icons at 14px, `--ctp-overlay1` default, `--ctp-text` on hover.
### Tabs
Used in detail panes and module sub-views:
```css
display: flex;
gap: 0;
border-bottom: 2px solid var(--ctp-surface0);
```
| State | Style |
|-------|-------|
| Default | `padding: 0.5rem 1rem`, `--ctp-subtext0` text, no border |
| Hover | `--ctp-text` text |
| Active | `--ctp-text` text, `font-weight: 600`, `border-bottom: 2px solid --ctp-mauve` (overlaps container border) |
### Section Dividers
Used to visually group form fields:
```css
display: flex;
align-items: center;
gap: 0.75rem;
grid-column: 1 / -1; /* span full form grid */
margin-top: 0.75rem;
```
Contains a label (`11px`, uppercase, `--ctp-overlay0`) and a horizontal line (`flex: 1`, `1px solid --ctp-surface0`).
### Sidebar Sections
Stacked vertically within detail panes:
```css
padding: 1rem 1.25rem;
border-bottom: 1px solid var(--ctp-surface0);
```
Last section has no bottom border. Section titles follow the section header typography (11px, uppercase, `--ctp-overlay0`).
### Tooltips
Appear on hover after a 300ms delay. Position: above the target element by default, flip below if insufficient space.
```css
background: var(--ctp-surface0);
border: 1px solid var(--ctp-surface1);
border-radius: 4px;
padding: 0.3rem 0.6rem;
font-size: 11px;
color: var(--ctp-text);
box-shadow: 0 4px 12px rgba(17, 17, 27, 0.4);
```
### Breadcrumbs
Module navigation breadcrumbs:
```
Module Name > List View > Record Name > Sub-view
```
Separator: `>` character in `--ctp-overlay0`. Segments are clickable links in `--ctp-subtext1`. Active (final) segment is `--ctp-text` at `font-weight: 600`.
### Dropdowns / Selects
Follow the input base style. The dropdown menu:
```css
background: var(--ctp-surface0);
border: 1px solid var(--ctp-surface1);
border-radius: 6px;
box-shadow: 0 8px 24px rgba(17, 17, 27, 0.5);
padding: 0.25rem;
max-height: 240px;
overflow-y: auto;
```
Menu items:
```css
padding: 0.4rem 0.65rem;
border-radius: 4px;
font-size: 12px;
color: var(--ctp-text);
cursor: pointer;
```
Hover: `background: --ctp-surface1`. Selected: `background: rgba(203, 166, 247, 0.12)`, `color: --ctp-mauve`, `font-weight: 600`.
---
## Icons
Use [Lucide](https://lucide.dev) icons. Size: 14px for inline/table contexts, 16px for buttons and navigation, 20px for page headers and empty states.
Stroke width: 1.5px (Lucide default). Color inherits from parent text color unless explicitly set.
Do not mix icon libraries. If Lucide does not have a suitable icon, request one be added or create a custom SVG following Lucide's 24×24 grid and stroke conventions.
---
## Transitions & Animation
All interactive state changes use `transition: all 0.15s ease`. This applies to hover, focus, active, and open/close states.
No entrance animations on page load. Content renders immediately. Skeleton loaders are acceptable for async data using a pulsing `--ctp-surface0``--ctp-surface1` gradient.
Dropdown menus and tooltips appear instantly (no slide/fade). Collapse/expand panels (if used) transition `max-height` at `0.2s ease`.
---
## Styling Implementation
Silo's React frontend uses **inline `React.CSSProperties` objects** with `var(--ctp-*)` token references. This is the project convention and must not be changed.
### Rules
- No CSS modules, no Tailwind, no external CSS-in-JS libraries.
- Styles are defined as `const` objects at the top of each component file.
- Shared style patterns (button base, input base) can be extracted to a `styles/` directory as exported `CSSProperties` objects.
- Use `as const` or `as React.CSSProperties` for type safety.
- Pseudo-classes (`:hover`, `:focus`) require state-driven inline styles or a thin CSS file for the base pseudo-class rules.
### Example
```typescript
const styles = {
container: {
display: 'grid',
gridTemplateColumns: '1fr 360px',
height: '100%',
overflow: 'hidden',
} as React.CSSProperties,
sidebar: {
background: 'var(--ctp-mantle)',
borderLeft: '1px solid var(--ctp-surface0)',
display: 'flex',
flexDirection: 'column' as const,
overflowY: 'auto' as const,
} as React.CSSProperties,
};
```
### Pseudo-class CSS
A single `silo-base.css` file provides pseudo-class rules that cannot be expressed inline:
```css
/* Hover, focus, and active states for core interactive elements */
.silo-input:hover { border-color: var(--ctp-overlay0); }
.silo-input:focus { border-color: var(--ctp-mauve); box-shadow: 0 0 0 0.2rem rgba(203, 166, 247, 0.25); }
.silo-btn:hover { /* per-tier overrides */ }
.silo-row:hover { background: var(--ctp-surface0); }
```
Components apply the corresponding class names alongside their inline styles. This is the only place class-based styling is used.
---
## Do / Don't
| Do | Don't |
|----|-------|
| Use `var(--ctp-*)` for every color | Hardcode hex values |
| Use the 4px spacing scale | Use arbitrary padding/margins |
| Use Lucide icons at standard sizes | Mix icon libraries |
| Use inline `CSSProperties` | Use CSS modules or Tailwind |
| One primary button per visible context | Multiple competing primary buttons |
| Use translucent accent backgrounds for badges | Use solid bright backgrounds for badges |
| Use icon buttons for row-level table actions | Use text links in table rows |
| Define styles as `const` at file top | Inline style objects in JSX |
| Show tooltips on icon-only buttons | Leave icon buttons unlabeled |
| Use section dividers to group form fields | Use cards or borders around field groups |
| Follow the breadcrumb pattern for navigation | Use nested tab bars |
---
## Appendix: CSS Custom Properties Block
Paste this at the root of the application stylesheet:
```css
:root {
--ctp-rosewater: #f5e0dc;
--ctp-flamingo: #f2cdcd;
--ctp-pink: #f5c2e7;
--ctp-mauve: #cba6f7;
--ctp-red: #f38ba8;
--ctp-maroon: #eba0ac;
--ctp-peach: #fab387;
--ctp-yellow: #f9e2af;
--ctp-green: #a6e3a1;
--ctp-teal: #94e2d5;
--ctp-sky: #89dceb;
--ctp-sapphire: #74c7ec;
--ctp-blue: #89b4fa;
--ctp-lavender: #b4befe;
--ctp-text: #cdd6f4;
--ctp-subtext1: #bac2de;
--ctp-subtext0: #a6adc8;
--ctp-overlay2: #9399b2;
--ctp-overlay1: #7f849c;
--ctp-overlay0: #6c7086;
--ctp-surface2: #585b70;
--ctp-surface1: #45475a;
--ctp-surface0: #313244;
--ctp-base: #1e1e2e;
--ctp-mantle: #181825;
--ctp-crust: #11111b;
}
```

View File

@@ -0,0 +1,364 @@
# Worker System Specification
**Status:** Draft
**Last Updated:** 2026-02-13
---
## 1. Purpose
The worker system provides async compute job execution for Silo. Jobs are defined as YAML files, managed by the Silo server, and executed by external runner processes. The system is general-purpose -- while DAG validation is the first use case, it supports any compute workload: geometry export, thumbnail rendering, FEA/CFD batch jobs, report generation, and data migration.
---
## 2. Architecture
```
YAML Job Definitions (files on disk, version-controllable)
|
v
Silo Server (parser, scheduler, state machine, REST API, SSE events)
|
v
Runners (silorunner binary, polls via REST, executes Headless Create)
```
**Three layers:**
1. **Job definitions** -- YAML files in a configurable directory (default `/etc/silo/jobdefs`). Each file defines a job type: what triggers it, what it operates on, what computation to perform, and what runner capabilities are required. These are the source of truth and can be version-controlled alongside other Silo config.
2. **Silo server** -- Parses YAML definitions on startup and upserts them into the `job_definitions` table. Creates job instances when triggers fire (revision created, BOM changed, manual). Manages job lifecycle, enforces timeouts, and broadcasts status via SSE.
3. **Runners** -- Separate `silorunner` processes that authenticate with Silo via API tokens, poll for available jobs, claim them atomically, execute the compute, and report results. A runner host must have Headless Create and silo-mod installed for geometry jobs.
---
## 3. Job Definition Format
Job definitions are YAML files with the following structure:
```yaml
job:
name: assembly-validate
version: 1
description: "Validate assembly by rebuilding its dependency subgraph"
trigger:
type: revision_created # revision_created, bom_changed, manual, schedule
filter:
item_type: assembly # only trigger for assemblies
scope:
type: assembly # item, assembly, project
compute:
type: validate # validate, rebuild, diff, export, custom
command: create-validate # runner-side command identifier
args: # passed to runner as JSON
rebuild_mode: incremental
check_interference: true
runner:
tags: [create] # required runner capabilities
timeout: 900 # seconds before job is marked failed (default 600)
max_retries: 2 # retry count on failure (default 1)
priority: 50 # lower = higher priority (default 100)
```
### 3.1 Trigger Types
| Type | Description |
|------|-------------|
| `revision_created` | Fires when a new revision is created on an item matching the filter |
| `bom_changed` | Fires when a BOM merge completes |
| `manual` | Only triggered via `POST /api/jobs` |
| `schedule` | Future: cron-like scheduling (not yet implemented) |
### 3.2 Trigger Filters
The `filter` map supports key-value matching against item properties:
| Key | Description |
|-----|-------------|
| `item_type` | Match item type: `part`, `assembly`, `drawing`, etc. |
| `schema` | Match schema name |
All filter keys must match for the trigger to fire. An empty filter matches all items.
### 3.3 Scope Types
| Type | Description |
|------|-------------|
| `item` | Job operates on a single item |
| `assembly` | Job operates on an assembly and its BOM tree |
| `project` | Job operates on all items in a project |
### 3.4 Compute Commands
The `command` field identifies what the runner should execute. Built-in commands:
| Command | Description |
|---------|-------------|
| `create-validate` | Open file in Headless Create, rebuild features, report validation results |
| `create-export` | Open file, export to specified format (STEP, IGES, 3MF) |
| `create-dag-extract` | Open file, extract feature DAG, output as JSON |
| `create-thumbnail` | Open file, render thumbnail image |
Custom commands can be added by extending silo-mod's `silo.runner` module.
---
## 4. Job Lifecycle
```
pending → claimed → running → completed
→ failed
→ cancelled
```
| State | Description |
|-------|-------------|
| `pending` | Job created, waiting for a runner to claim it |
| `claimed` | Runner has claimed the job. `expires_at` is set. |
| `running` | Runner has started execution (reported via progress update) |
| `completed` | Runner reported success. `result` JSONB contains output. |
| `failed` | Runner reported failure, timeout expired, or max retries exceeded |
| `cancelled` | Admin cancelled the job before completion |
### 4.1 Claim Semantics
Runners claim jobs via `POST /api/runner/claim`. The server uses PostgreSQL's `SELECT FOR UPDATE SKIP LOCKED` to ensure exactly-once delivery:
```sql
WITH claimable AS (
SELECT id FROM jobs
WHERE status = 'pending'
AND runner_tags <@ $2::text[]
ORDER BY priority ASC, created_at ASC
LIMIT 1
FOR UPDATE SKIP LOCKED
)
UPDATE jobs SET
status = 'claimed',
runner_id = $1,
claimed_at = now(),
expires_at = now() + (timeout_seconds || ' seconds')::interval
FROM claimable
WHERE jobs.id = claimable.id
RETURNING jobs.*;
```
The `runner_tags <@ $2::text[]` condition ensures the runner has all tags required by the job. A runner with tags `["create", "linux", "gpu"]` can claim a job requiring `["create"]`, but not one requiring `["create", "windows"]`.
### 4.2 Timeout Enforcement
A background sweeper runs every 30 seconds (configurable via `jobs.job_timeout_check`) and marks expired jobs as failed:
```sql
UPDATE jobs SET status = 'failed', error_message = 'job timed out'
WHERE status IN ('claimed', 'running')
AND expires_at < now();
```
### 4.3 Retry
When a job fails and `retry_count < max_retries`, a new job is created with the same definition and scope, with `retry_count` incremented.
---
## 5. Runners
### 5.1 Registration
Runners are registered via `POST /api/runners` (admin only). The server generates a token (shown once) and stores the SHA-256 hash in the `runners` table. This follows the same pattern as API tokens in `internal/auth/token.go`.
### 5.2 Authentication
Runners authenticate via `Authorization: Bearer silo_runner_<token>`. A dedicated `RequireRunnerAuth` middleware validates the token against the `runners` table and injects a `RunnerIdentity` into the request context.
### 5.3 Heartbeat
Runners send `POST /api/runner/heartbeat` every 30 seconds. The server updates `last_heartbeat` and sets `status = 'online'`. A background sweeper marks runners as `offline` if their heartbeat is older than `runner_timeout` seconds (default 90).
### 5.4 Tags
Each runner declares capability tags (e.g., `["create", "linux", "gpu"]`). Jobs require specific tags via the `runner.tags` field in their YAML definition. A runner can only claim jobs whose required tags are a subset of the runner's tags.
### 5.5 Runner Config
The `silorunner` binary reads its config from a YAML file:
```yaml
server_url: "https://silo.example.com"
token: "silo_runner_abc123..."
name: "worker-01"
tags: ["create", "linux"]
poll_interval: 5 # seconds between claim attempts
create_path: "/usr/bin/create" # path to Headless Create binary (with silo-mod installed)
```
Or via environment variables: `SILO_RUNNER_SERVER_URL`, `SILO_RUNNER_TOKEN`, etc.
### 5.6 Deployment
Runner prerequisites:
- `silorunner` binary (built from `cmd/silorunner/`)
- Headless Create (Kindred's fork of FreeCAD) with silo-mod workbench installed
- Network access to Silo server API
Runners can be deployed as:
- Bare metal processes alongside Create installations
- Docker containers with Create pre-installed
- Scaled horizontally by registering multiple runners with different names
---
## 6. Job Log
Each job has an append-only log stored in the `job_log` table. Runners append entries via `POST /api/runner/jobs/{jobID}/log`:
```json
{
"level": "info",
"message": "Rebuilding Pad003...",
"metadata": {"node_key": "Pad003", "progress_pct": 45}
}
```
Log levels: `debug`, `info`, `warn`, `error`.
---
## 7. SSE Events
All job lifecycle transitions are broadcast via Silo's SSE broker. Clients subscribe to `/api/events` and receive:
| Event Type | Payload | When |
|------------|---------|------|
| `job.created` | `{id, definition_name, item_id, status, priority}` | Job created |
| `job.claimed` | `{id, runner_id, runner_name}` | Runner claims job |
| `job.progress` | `{id, progress, progress_message}` | Runner reports progress (0-100) |
| `job.completed` | `{id, result_summary, duration_seconds}` | Job completed successfully |
| `job.failed` | `{id, error_message}` | Job failed |
| `job.cancelled` | `{id, cancelled_by}` | Admin cancelled job |
| `runner.online` | `{id, name, tags}` | Runner heartbeat (first after offline) |
| `runner.offline` | `{id, name}` | Runner heartbeat timeout |
---
## 8. REST API
### 8.1 Job Endpoints (user-facing, require auth)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `GET` | `/api/jobs` | viewer | List jobs (filterable by status, item, definition) |
| `GET` | `/api/jobs/{jobID}` | viewer | Get job details |
| `GET` | `/api/jobs/{jobID}/logs` | viewer | Get job log entries |
| `POST` | `/api/jobs` | editor | Manually trigger a job |
| `POST` | `/api/jobs/{jobID}/cancel` | editor | Cancel a pending/running job |
### 8.2 Job Definition Endpoints
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `GET` | `/api/job-definitions` | viewer | List loaded definitions |
| `GET` | `/api/job-definitions/{name}` | viewer | Get specific definition |
| `POST` | `/api/job-definitions/reload` | admin | Re-read YAML from disk |
### 8.3 Runner Management Endpoints (admin)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `GET` | `/api/runners` | admin | List registered runners |
| `POST` | `/api/runners` | admin | Register runner (returns token) |
| `DELETE` | `/api/runners/{runnerID}` | admin | Delete runner |
### 8.4 Runner-Facing Endpoints (runner token auth)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `POST` | `/api/runner/heartbeat` | runner | Send heartbeat |
| `POST` | `/api/runner/claim` | runner | Claim next available job |
| `PUT` | `/api/runner/jobs/{jobID}/progress` | runner | Report progress |
| `POST` | `/api/runner/jobs/{jobID}/complete` | runner | Report completion with result |
| `POST` | `/api/runner/jobs/{jobID}/fail` | runner | Report failure |
| `POST` | `/api/runner/jobs/{jobID}/log` | runner | Append log entry |
| `PUT` | `/api/runner/jobs/{jobID}/dag` | runner | Sync DAG results after compute |
---
## 9. Configuration
Add to `config.yaml`:
```yaml
jobs:
directory: /etc/silo/jobdefs # path to YAML job definitions
runner_timeout: 90 # seconds before marking runner offline
job_timeout_check: 30 # seconds between timeout sweeps
default_priority: 100 # default job priority
```
---
## 10. Example Job Definitions
### Assembly Validation
```yaml
job:
name: assembly-validate
version: 1
description: "Validate assembly by rebuilding its dependency subgraph"
trigger:
type: revision_created
filter:
item_type: assembly
scope:
type: assembly
compute:
type: validate
command: create-validate
args:
rebuild_mode: incremental
check_interference: true
runner:
tags: [create]
timeout: 900
max_retries: 2
priority: 50
```
### STEP Export
```yaml
job:
name: part-export-step
version: 1
description: "Export a part to STEP format"
trigger:
type: manual
scope:
type: item
compute:
type: export
command: create-export
args:
format: step
output_key_template: "exports/{part_number}_rev{revision}.step"
runner:
tags: [create]
timeout: 300
max_retries: 1
priority: 100
```
---
## 11. References
- [DAG.md](DAG.md) -- Dependency DAG specification
- [MULTI_USER_EDITS.md](MULTI_USER_EDITS.md) -- Multi-user editing specification
- [ROADMAP.md](ROADMAP.md) -- Tier 0 Job Queue Infrastructure, Tier 1 Headless Create

View File

@@ -118,7 +118,7 @@ The server provides the REST API and ODS endpoints consumed by these clients.
| [docs/AUTH_USER_GUIDE.md](docs/AUTH_USER_GUIDE.md) | User guide for login, tokens, and roles |
| [docs/GAP_ANALYSIS.md](docs/GAP_ANALYSIS.md) | Gap analysis and revision control roadmap |
| [docs/COMPONENT_AUDIT.md](docs/COMPONENT_AUDIT.md) | Component audit tool design |
| [ROADMAP.md](ROADMAP.md) | Feature roadmap and SOLIDWORKS PDM comparison |
| [docs/ROADMAP.md](docs/ROADMAP.md) | Platform roadmap, dependency tiers, and gap summary |
| [frontend-spec.md](frontend-spec.md) | React SPA frontend specification |
## License