Add beads for query and clash features

New issues:
- ifcurl-8rf (P2): Server /query endpoint + _sandboxed_query
- ifcurl-19h (P2): Renderer clash visibility mode
- ifcurl-2iv (P3): Viewer query results table (blocked on ifcurl-8rf)
- ifcurl-4u3 (P3): Viewer query creation/editing UI
- ifcurl-982 (P3): Viewer clash visibility mode display

https://claude.ai/code/session_01NBsytCd6L7UQPiKbcLn4kn
This commit is contained in:
Claude 2026-05-09 08:09:10 +00:00
parent bbaec96d34
commit 56c36b51e9

View file

@ -2,6 +2,7 @@
{"_type":"issue","id":"ifcurl-p60","title":"Viewer: no element click-to-identify — can't get GlobalId or properties","description":"There is no way to click on a mesh in the viewer and see which IFC element it represents. Reviewers can see geometry but cannot reference specific elements — they can't discover a GlobalId to put in a selector URL, can't see the element name/type/Psets, and can't say 'this specific wall' in a BCF or Forgejo comment. This breaks the collaboration workflow at its foundation: every useful feedback comment needs to identify specific elements. Need: click or hover on a surface to highlight it and show a properties panel (name, type, GlobalId, key Psets). The GlobalId should be copyable into the selector field or URL. The ThatOpen components library provides the tools for this (OBC.IfcRelationsIndexer, element property queries).","status":"closed","priority":1,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T11:02:33Z","created_by":"Bruno Postle","updated_at":"2026-04-24T11:47:23Z","started_at":"2026-04-24T11:14:57Z","closed_at":"2026-04-24T11:47:23Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-p60","title":"Viewer: no element click-to-identify — can't get GlobalId or properties","description":"There is no way to click on a mesh in the viewer and see which IFC element it represents. Reviewers can see geometry but cannot reference specific elements — they can't discover a GlobalId to put in a selector URL, can't see the element name/type/Psets, and can't say 'this specific wall' in a BCF or Forgejo comment. This breaks the collaboration workflow at its foundation: every useful feedback comment needs to identify specific elements. Need: click or hover on a surface to highlight it and show a properties panel (name, type, GlobalId, key Psets). The GlobalId should be copyable into the selector field or URL. The ThatOpen components library provides the tools for this (OBC.IfcRelationsIndexer, element property queries).","status":"closed","priority":1,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T11:02:33Z","created_by":"Bruno Postle","updated_at":"2026-04-24T11:47:23Z","started_at":"2026-04-24T11:14:57Z","closed_at":"2026-04-24T11:47:23Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-4l7","title":"viewer.html: scale= URLs don't load in orthographic mode","description":"applyCameraParam() reads the camera= and fov= parameters from the URL and applies them, but never reads scale= or switches the camera to orthographic (parallel) projection. URLs like ?camera=...\u0026scale=50 will load in perspective mode instead of orthographic. The OBC OrthoPerspectiveCamera can switch modes, but the code path to set parallel projection and apply the scale value is missing from applyCameraParam.","status":"closed","priority":1,"issue_type":"bug","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T09:04:51Z","created_by":"Bruno Postle","updated_at":"2026-04-24T10:56:29Z","started_at":"2026-04-24T10:50:19Z","closed_at":"2026-04-24T10:56:29Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-4l7","title":"viewer.html: scale= URLs don't load in orthographic mode","description":"applyCameraParam() reads the camera= and fov= parameters from the URL and applies them, but never reads scale= or switches the camera to orthographic (parallel) projection. URLs like ?camera=...\u0026scale=50 will load in perspective mode instead of orthographic. The OBC OrthoPerspectiveCamera can switch modes, but the code path to set parallel projection and apply the scale value is missing from applyCameraParam.","status":"closed","priority":1,"issue_type":"bug","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T09:04:51Z","created_by":"Bruno Postle","updated_at":"2026-04-24T10:56:29Z","started_at":"2026-04-24T10:50:19Z","closed_at":"2026-04-24T10:56:29Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-362","title":"Add missing server-config files: gitconfig-ifcmerge and gitattributes","description":"forgejo/README.md documents deploying two files that don't exist in the repo: forgejo/server-config/gitconfig-ifcmerge and forgejo/server-config/gitattributes. Both are required for the ifcmerge git merge driver to work in bare Forgejo repos. The README even includes 'sudo cp forgejo/server-config/gitattributes /etc/gitattributes' and 'sudo git config --system include.path .../gitconfig-ifcmerge', but the files themselves are absent. Anyone following the deployment instructions will hit a 'file not found' error. Need to create both files with the content described in the README.","status":"closed","priority":1,"issue_type":"bug","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T09:04:31Z","created_by":"Bruno Postle","updated_at":"2026-04-24T10:51:47Z","started_at":"2026-04-24T10:50:15Z","closed_at":"2026-04-24T10:51:47Z","close_reason":"Files already exist: forgejo/server-config/gitconfig-ifcmerge and gitattributes are both present and correct. Missed in initial review.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-362","title":"Add missing server-config files: gitconfig-ifcmerge and gitattributes","description":"forgejo/README.md documents deploying two files that don't exist in the repo: forgejo/server-config/gitconfig-ifcmerge and forgejo/server-config/gitattributes. Both are required for the ifcmerge git merge driver to work in bare Forgejo repos. The README even includes 'sudo cp forgejo/server-config/gitattributes /etc/gitattributes' and 'sudo git config --system include.path .../gitconfig-ifcmerge', but the files themselves are absent. Anyone following the deployment instructions will hit a 'file not found' error. Need to create both files with the content described in the README.","status":"closed","priority":1,"issue_type":"bug","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T09:04:31Z","created_by":"Bruno Postle","updated_at":"2026-04-24T10:51:47Z","started_at":"2026-04-24T10:50:15Z","closed_at":"2026-04-24T10:51:47Z","close_reason":"Files already exist: forgejo/server-config/gitconfig-ifcmerge and gitattributes are both present and correct. Missed in initial review.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-8rf","title":"Server: add /query endpoint for attribute/property retrieval","description":"Add GET and POST /query endpoints to service.py (mirroring the /select pattern). The endpoint resolves an ifc:// URL's selector, then for each matched element retrieves the attribute or property value named by the query parameter (dot-notation: Name, Pset_WallCommon.FireRating). Returns JSON {GlobalId: value, ...}, excluding elements with no GlobalId and attributes that resolve to entity references rather than scalars. Add _sandboxed_query(ifc_bytes, selector, query_path) to render_service.py and a matching _query_via_socket() delegation path. Reuse Tier 2/3 caches for IFC bytes and GUID sets. No Tier 4 caching — responses depend on the query path, not just the URL hash.","status":"open","priority":2,"issue_type":"feature","owner":"noreply@anthropic.com","created_at":"2026-05-09T08:08:29Z","created_by":"Claude","updated_at":"2026-05-09T08:08:29Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-b1c","title":"Implement OpenCDE BCF API on Forgejo","description":"Expose a BCF 3.0 REST API as a Python route group in the preview service, proxied at /bcf/3.0/ on the Forgejo hostname via nginx/Caddy.\n\n## Architecture\n\nPython routes added to service.py alongside the existing /preview and /bcf endpoints. No new Forgejo Go code — the service forwards the user's Authorization: Bearer header verbatim to Forgejo's REST API on localhost, so Forgejo's own auth middleware enforces per-user permissions. No service account or machine token required.\n\nBCF \u003c-\u003e ifc:// conversion stays entirely in Python: bcf.py (ifc:// -\u003e BCF, already exists) and the reverse direction implemented in ifcurl-l50.\n\n## Design\n\nThe BCF API is a stateless translation layer over Forgejo's REST API. No Forgejo recompilation, no schema changes, no new Go code.\n\n**Storage:** ifc:// URLs in issue and comment bodies are the viewpoint format. This is already what the viewer Issue button produces. The BCF\u003c-\u003eifc:// conversion is specified in SPECIFICATION.md §6.\n\n**Mapping:**\n\n| BCF resource | Forgejo |\n|---|---|\n| Project | Repository (project_id = owner/repo) |\n| Topic | Issue |\n| Topic guid | Derived from issue ID |\n| Comment | Issue comment |\n| Viewpoint | ifc:// URL found in issue/comment body |\n| Viewpoint guid | Derived from comment ID |\n| Snapshot | ifc:// URL proxied through preview service |\n\n**Auth:** BCF client sends Authorization: Bearer \u003cforgejo-token\u003e. Service forwards it to Forgejo REST API. No credential storage, no service token.\n\n**Read viewpoints:** scan issue/comment bodies for ifc:// URLs, convert each to a BCF viewpoint object on the fly via the §6 mapping.\n\n**Write viewpoints:** convert incoming BCF viewpoint to an ifc:// URL (ifcurl-l50), post as a new Forgejo comment.\n\n**Snapshot:** GET .../viewpoints/{guid}/snapshot proxies the stored ifc:// URL through the existing /preview endpoint.\n\n## Minimum viable endpoints\n\n- GET /bcf/3.0/projects\n- GET /bcf/3.0/projects/{id}\n- GET/POST /bcf/3.0/projects/{id}/topics\n- GET/PUT /bcf/3.0/projects/{id}/topics/{guid}\n- GET/POST /bcf/3.0/projects/{id}/topics/{guid}/comments\n- GET/POST /bcf/3.0/projects/{id}/topics/{guid}/viewpoints\n- GET /bcf/3.0/projects/{id}/topics/{guid}/viewpoints/{guid}\n- GET /bcf/3.0/projects/{id}/topics/{guid}/viewpoints/{guid}/snapshot\n- GET /bcf/3.0/projects/{id}/extensions (static minimal response)\n\n## Prerequisites\n\n- ifcurl-lwl: Foundation API discovery so BCF clients can locate this endpoint via OpenCDE auto-discovery\n- ifcurl-l50: BCF -\u003e ifc:// URL conversion needed for POST /viewpoints","status":"closed","priority":2,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-28T22:55:11Z","created_by":"Bruno Postle","updated_at":"2026-04-29T18:39:11Z","closed_at":"2026-04-29T18:39:11Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-b1c","depends_on_id":"ifcurl-l50","type":"blocks","created_at":"2026-04-29T18:44:06Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-b1c","depends_on_id":"ifcurl-lwl","type":"blocks","created_at":"2026-04-29T18:44:05Z","created_by":"Claude","metadata":"{}"}],"dependency_count":2,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-b1c","title":"Implement OpenCDE BCF API on Forgejo","description":"Expose a BCF 3.0 REST API as a Python route group in the preview service, proxied at /bcf/3.0/ on the Forgejo hostname via nginx/Caddy.\n\n## Architecture\n\nPython routes added to service.py alongside the existing /preview and /bcf endpoints. No new Forgejo Go code — the service forwards the user's Authorization: Bearer header verbatim to Forgejo's REST API on localhost, so Forgejo's own auth middleware enforces per-user permissions. No service account or machine token required.\n\nBCF \u003c-\u003e ifc:// conversion stays entirely in Python: bcf.py (ifc:// -\u003e BCF, already exists) and the reverse direction implemented in ifcurl-l50.\n\n## Design\n\nThe BCF API is a stateless translation layer over Forgejo's REST API. No Forgejo recompilation, no schema changes, no new Go code.\n\n**Storage:** ifc:// URLs in issue and comment bodies are the viewpoint format. This is already what the viewer Issue button produces. The BCF\u003c-\u003eifc:// conversion is specified in SPECIFICATION.md §6.\n\n**Mapping:**\n\n| BCF resource | Forgejo |\n|---|---|\n| Project | Repository (project_id = owner/repo) |\n| Topic | Issue |\n| Topic guid | Derived from issue ID |\n| Comment | Issue comment |\n| Viewpoint | ifc:// URL found in issue/comment body |\n| Viewpoint guid | Derived from comment ID |\n| Snapshot | ifc:// URL proxied through preview service |\n\n**Auth:** BCF client sends Authorization: Bearer \u003cforgejo-token\u003e. Service forwards it to Forgejo REST API. No credential storage, no service token.\n\n**Read viewpoints:** scan issue/comment bodies for ifc:// URLs, convert each to a BCF viewpoint object on the fly via the §6 mapping.\n\n**Write viewpoints:** convert incoming BCF viewpoint to an ifc:// URL (ifcurl-l50), post as a new Forgejo comment.\n\n**Snapshot:** GET .../viewpoints/{guid}/snapshot proxies the stored ifc:// URL through the existing /preview endpoint.\n\n## Minimum viable endpoints\n\n- GET /bcf/3.0/projects\n- GET /bcf/3.0/projects/{id}\n- GET/POST /bcf/3.0/projects/{id}/topics\n- GET/PUT /bcf/3.0/projects/{id}/topics/{guid}\n- GET/POST /bcf/3.0/projects/{id}/topics/{guid}/comments\n- GET/POST /bcf/3.0/projects/{id}/topics/{guid}/viewpoints\n- GET /bcf/3.0/projects/{id}/topics/{guid}/viewpoints/{guid}\n- GET /bcf/3.0/projects/{id}/topics/{guid}/viewpoints/{guid}/snapshot\n- GET /bcf/3.0/projects/{id}/extensions (static minimal response)\n\n## Prerequisites\n\n- ifcurl-lwl: Foundation API discovery so BCF clients can locate this endpoint via OpenCDE auto-discovery\n- ifcurl-l50: BCF -\u003e ifc:// URL conversion needed for POST /viewpoints","status":"closed","priority":2,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-28T22:55:11Z","created_by":"Bruno Postle","updated_at":"2026-04-29T18:39:11Z","closed_at":"2026-04-29T18:39:11Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-b1c","depends_on_id":"ifcurl-l50","type":"blocks","created_at":"2026-04-29T18:44:06Z","created_by":"Claude","metadata":"{}"},{"issue_id":"ifcurl-b1c","depends_on_id":"ifcurl-lwl","type":"blocks","created_at":"2026-04-29T18:44:05Z","created_by":"Claude","metadata":"{}"}],"dependency_count":2,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-962","title":"forgejo: replace Go markdown extension with JS, eliminate required Go compile","description":"ifc_url.go is a Goldmark AST extension that requires patching and recompiling Forgejo to work. This is painful when dev environment (Fedora) differs from deployment (Docker) — compiler flags, static linking, build tags must all match. The goal is to make the ifc:// preview feature work with zero Go compilation, via pure JS asset deployment.\n\nPlan:\n1. Add querySelectorAll('a[href^=\"ifc://\"]') scanning to ifcurl.js — replace matched anchors with figure elements (preview image + viewer link + ifc:// URL). Goldmark already renders [title](ifc://...) as \u003ca href=\"ifc://...\"\u003etitle\u003c/a\u003e without any extension, so this covers all markdown link syntax.\n2. Change the Issue button in viewer.js to emit [view](ifc://...) markdown link syntax instead of a bare URL — so that user-generated issue bodies produce linkable anchors Goldmark will render, not plain text.\n3. The existing Go extension (ifc_url.go) and its markdown.go registration can be removed on the next Forgejo upgrade; the current patched binary continues to work in the meantime.\n\nAcceptance: after this change, deploying new ifcurl features only requires copying JS assets — no Forgejo rebuild needed.","status":"closed","priority":2,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T06:58:15Z","created_by":"Bruno Postle","updated_at":"2026-04-27T07:25:09Z","started_at":"2026-04-27T06:58:48Z","closed_at":"2026-04-27T07:25:09Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-962","title":"forgejo: replace Go markdown extension with JS, eliminate required Go compile","description":"ifc_url.go is a Goldmark AST extension that requires patching and recompiling Forgejo to work. This is painful when dev environment (Fedora) differs from deployment (Docker) — compiler flags, static linking, build tags must all match. The goal is to make the ifc:// preview feature work with zero Go compilation, via pure JS asset deployment.\n\nPlan:\n1. Add querySelectorAll('a[href^=\"ifc://\"]') scanning to ifcurl.js — replace matched anchors with figure elements (preview image + viewer link + ifc:// URL). Goldmark already renders [title](ifc://...) as \u003ca href=\"ifc://...\"\u003etitle\u003c/a\u003e without any extension, so this covers all markdown link syntax.\n2. Change the Issue button in viewer.js to emit [view](ifc://...) markdown link syntax instead of a bare URL — so that user-generated issue bodies produce linkable anchors Goldmark will render, not plain text.\n3. The existing Go extension (ifc_url.go) and its markdown.go registration can be removed on the next Forgejo upgrade; the current patched binary continues to work in the meantime.\n\nAcceptance: after this change, deploying new ifcurl features only requires copying JS assets — no Forgejo rebuild needed.","status":"closed","priority":2,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T06:58:15Z","created_by":"Bruno Postle","updated_at":"2026-04-27T07:25:09Z","started_at":"2026-04-27T06:58:48Z","closed_at":"2026-04-27T07:25:09Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-22n","title":"viewer: add ifc:// URL and clickable image link to embedded snapshots","description":"Forgejo commit pages and pull requests embed IFC snapshots as visual diffs. Each snapshot should have two additions: (1) the ifc:// URL that addresses this exact view at the commit hash displayed as text alongside the image, and (2) the snapshot image itself should be a clickable link that opens the viewer at this view. This makes snapshots navigable and shareable.","status":"closed","priority":2,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T05:36:16Z","created_by":"Bruno Postle","updated_at":"2026-04-27T05:59:52Z","started_at":"2026-04-27T05:59:51Z","closed_at":"2026-04-27T05:59:52Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-22n","depends_on_id":"ifcurl-5a6","type":"blocks","created_at":"2026-04-27T06:37:10Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-22n","title":"viewer: add ifc:// URL and clickable image link to embedded snapshots","description":"Forgejo commit pages and pull requests embed IFC snapshots as visual diffs. Each snapshot should have two additions: (1) the ifc:// URL that addresses this exact view at the commit hash displayed as text alongside the image, and (2) the snapshot image itself should be a clickable link that opens the viewer at this view. This makes snapshots navigable and shareable.","status":"closed","priority":2,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-27T05:36:16Z","created_by":"Bruno Postle","updated_at":"2026-04-27T05:59:52Z","started_at":"2026-04-27T05:59:51Z","closed_at":"2026-04-27T05:59:52Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-22n","depends_on_id":"ifcurl-5a6","type":"blocks","created_at":"2026-04-27T06:37:10Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
@ -101,7 +102,7 @@
{"_type":"issue","id":"ifcurl-lcr","title":"Phase 4: Bonsai 'Copy view URL' button","description":"Add a button to Bonsai that generates an ifc:// URL from the current state: git remote/ref/file path, active selection as IfcOpenShell selector, current camera as camera+fov or scale params in IFC world coordinates, active clipping planes as clip params, current visibility mode. Default to commit hash ref; secondary option for @heads/ ref.","status":"deferred","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:55Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:10Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-lcr","depends_on_id":"ifcurl-0oj","type":"blocks","created_at":"2026-04-23T06:49:01Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-lcr","title":"Phase 4: Bonsai 'Copy view URL' button","description":"Add a button to Bonsai that generates an ifc:// URL from the current state: git remote/ref/file path, active selection as IfcOpenShell selector, current camera as camera+fov or scale params in IFC world coordinates, active clipping planes as clip params, current visibility mode. Default to commit hash ref; secondary option for @heads/ ref.","status":"deferred","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:55Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:10Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-lcr","depends_on_id":"ifcurl-0oj","type":"blocks","created_at":"2026-04-23T06:49:01Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-0oj","title":"Phase 4: Bonsai ifc:// OS protocol handler","description":"Register ifc:// as an OS protocol handler in Bonsai on installation (Windows, macOS, Linux). On receiving a URL, resolve the git source, load the model, and apply the view state from the URL parameters (camera, selector, clipping planes, visibility mode). This is the foundation for all other Phase 4 work.","status":"deferred","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:45Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:09Z","defer_until":"2026-12-01T00:00:00Z","dependency_count":0,"dependent_count":3,"comment_count":0} {"_type":"issue","id":"ifcurl-0oj","title":"Phase 4: Bonsai ifc:// OS protocol handler","description":"Register ifc:// as an OS protocol handler in Bonsai on installation (Windows, macOS, Linux). On receiving a URL, resolve the git source, load the model, and apply the view state from the URL parameters (camera, selector, clipping planes, visibility mode). This is the foundation for all other Phase 4 work.","status":"deferred","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:45Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:09Z","defer_until":"2026-12-01T00:00:00Z","dependency_count":0,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"ifcurl-cyw","title":"Phase 3c: Verify Forgejo merge-ability check works with ifcmerge","description":"Investigate whether Forgejo's merge-ability check (the 'branches can be merged automatically' indicator) correctly reflects ifcmerge's ability to handle .ifc files. Determine if Forgejo runs a trial git merge or uses a heuristic. If needed, patch Forgejo to run a trial git merge --no-commit to get an accurate result.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:22Z","created_by":"Bruno Postle","updated_at":"2026-04-24T08:27:25Z","started_at":"2026-04-24T08:19:58Z","closed_at":"2026-04-24T08:27:25Z","close_reason":"Verified: git merge-tree --write-tree (Forgejo's code path for git ≥2.38) does invoke merge drivers. Bare repos require core.attributesFile in /etc/gitconfig — committed .gitattributes not read. Added gitattributes server-config file and updated deployment docs.","dependencies":[{"issue_id":"ifcurl-cyw","depends_on_id":"ifcurl-c69","type":"blocks","created_at":"2026-04-23T06:48:29Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-cyw","title":"Phase 3c: Verify Forgejo merge-ability check works with ifcmerge","description":"Investigate whether Forgejo's merge-ability check (the 'branches can be merged automatically' indicator) correctly reflects ifcmerge's ability to handle .ifc files. Determine if Forgejo runs a trial git merge or uses a heuristic. If needed, patch Forgejo to run a trial git merge --no-commit to get an accurate result.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:22Z","created_by":"Bruno Postle","updated_at":"2026-04-24T08:27:25Z","started_at":"2026-04-24T08:19:58Z","closed_at":"2026-04-24T08:27:25Z","close_reason":"Verified: git merge-tree --write-tree (Forgejo's code path for git ≥2.38) does invoke merge drivers. Bare repos require core.attributesFile in /etc/gitconfig — committed .gitattributes not read. Added gitattributes server-config file and updated deployment docs.","dependencies":[{"issue_id":"ifcurl-cyw","depends_on_id":"ifcurl-c69","type":"blocks","created_at":"2026-04-23T06:48:29Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-c69","title":"Phase 3c: Register ifcmerge as git merge driver on Forgejo server","description":"Configure ifcmerge as the git merge driver for .ifc files on the Forgejo server. Add to /etc/gitconfig or ~forgejo/.gitconfig: [merge \"ifcmerge\"] name = IFC merge driver / driver = ifcmerge %O %A %B %L. Add *.ifc merge=ifcmerge to server-side gitattributes. This allows Forgejo's 'merge automatically' path to invoke ifcmerge via git when merging .ifc files.","status":"closed","priority":3,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:21Z","created_by":"Bruno Postle","updated_at":"2026-04-24T08:15:20Z","closed_at":"2026-04-24T08:15:20Z","close_reason":"Documented ifcmerge driver registration (gitconfig-ifcmerge), gitattributes setup, merge direction constraint, and merge-commit strategy requirement","comments":[{"id":"dda02376-d2d8-4bd0-85b5-02753e31a722","issue_id":"ifcurl-c69","author":"Bruno Postle","text":"ifcmerge needs to be installed as a pair of merge tools because the merge process is asymmetrical and we need to be able to prefer one branch over another (because step-ids from one branch get rewritten in the merged file). In practice we prefer origin and/or main/master branches. there is code in the ifcopenshell bonsai ifcgit module for reference.","created_at":"2026-04-23T21:52:44Z"}],"dependency_count":0,"dependent_count":1,"comment_count":1} {"_type":"issue","id":"ifcurl-c69","title":"Phase 3c: Register ifcmerge as git merge driver on Forgejo server","description":"Configure ifcmerge as the git merge driver for .ifc files on the Forgejo server. Add to /etc/gitconfig or ~forgejo/.gitconfig: [merge \"ifcmerge\"] name = IFC merge driver / driver = ifcmerge %O %A %B %L. Add *.ifc merge=ifcmerge to server-side gitattributes. This allows Forgejo's 'merge automatically' path to invoke ifcmerge via git when merging .ifc files.","status":"closed","priority":3,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:21Z","created_by":"Bruno Postle","updated_at":"2026-04-24T08:15:20Z","closed_at":"2026-04-24T08:15:20Z","close_reason":"Documented ifcmerge driver registration (gitconfig-ifcmerge), gitattributes setup, merge direction constraint, and merge-commit strategy requirement","comments":[{"id":"60981100-d07f-4436-b1a5-a662d1c17b90","issue_id":"ifcurl-c69","author":"Bruno Postle","text":"ifcmerge needs to be installed as a pair of merge tools because the merge process is asymmetrical and we need to be able to prefer one branch over another (because step-ids from one branch get rewritten in the merged file). In practice we prefer origin and/or main/master branches. there is code in the ifcopenshell bonsai ifcgit module for reference.","created_at":"2026-04-23T21:52:44Z"}],"dependency_count":0,"dependent_count":1,"comment_count":1}
{"_type":"issue","id":"ifcurl-gxf","title":"Add minimal read-only OpenCDE Documents API","description":"Expose a minimal read-only OpenCDE Documents API that makes IFC files in git repos addressable as OpenCDE documents.\n\n## Architecture\n\nPython routes in the preview service, proxied at /documents/ on the Forgejo hostname via nginx/Caddy. Same pattern as the BCF API. Auth forwarded verbatim (Authorization: Bearer) — Forgejo enforces per-user repo permissions. No Go code, no Forgejo recompilation.\n\n## Design\n\ndocument_id is a base64url encoding of 'owner/repo/path', making it stable and opaque. version_index is the 1-based position of the commit in the file's git history (oldest=1, newest=N), derived by querying Forgejo's commits API with the file path filter.\n\nPOST /documents/1.0/document-versions returns all versions (up to 50 commits) for each requested document_id. Download URLs point at Forgejo's existing raw file endpoint: {forgejo_host}/{owner}/{repo}/raw/commit/{sha}/{path}.\n\nThe public Forgejo base URL for download links is derived from X-Forwarded-Host/X-Forwarded-Proto headers, same as the Foundation endpoint.\n\nThis validates the ifc:// CDE extension in SPECIFICATION.md §9 (document_id= parameter) and makes Forgejo discoverable as an OpenCDE server to any client that speaks the Documents API.","status":"closed","priority":4,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-28T22:41:30Z","created_by":"Bruno Postle","updated_at":"2026-04-29T19:27:30Z","started_at":"2026-04-29T18:48:04Z","closed_at":"2026-04-29T19:27:30Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-gxf","title":"Add minimal read-only OpenCDE Documents API","description":"Expose a minimal read-only OpenCDE Documents API that makes IFC files in git repos addressable as OpenCDE documents.\n\n## Architecture\n\nPython routes in the preview service, proxied at /documents/ on the Forgejo hostname via nginx/Caddy. Same pattern as the BCF API. Auth forwarded verbatim (Authorization: Bearer) — Forgejo enforces per-user repo permissions. No Go code, no Forgejo recompilation.\n\n## Design\n\ndocument_id is a base64url encoding of 'owner/repo/path', making it stable and opaque. version_index is the 1-based position of the commit in the file's git history (oldest=1, newest=N), derived by querying Forgejo's commits API with the file path filter.\n\nPOST /documents/1.0/document-versions returns all versions (up to 50 commits) for each requested document_id. Download URLs point at Forgejo's existing raw file endpoint: {forgejo_host}/{owner}/{repo}/raw/commit/{sha}/{path}.\n\nThe public Forgejo base URL for download links is derived from X-Forwarded-Host/X-Forwarded-Proto headers, same as the Foundation endpoint.\n\nThis validates the ifc:// CDE extension in SPECIFICATION.md §9 (document_id= parameter) and makes Forgejo discoverable as an OpenCDE server to any client that speaks the Documents API.","status":"closed","priority":4,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-28T22:41:30Z","created_by":"Bruno Postle","updated_at":"2026-04-29T19:27:30Z","started_at":"2026-04-29T18:48:04Z","closed_at":"2026-04-29T19:27:30Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-s1o","title":"viewer: extract inline JS from viewer.html into viewer.js","description":"viewer.html is ~1250 lines, almost entirely JavaScript. This makes it hard to edit with proper tooling (no syntax highlighting, linting, or go-to-definition). Extract the main viewer logic into a separate viewer.js file alongside viewer-url.js. The build.js step would need to copy it to the assets directory.","status":"closed","priority":4,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-25T23:16:36Z","created_by":"Bruno Postle","updated_at":"2026-04-26T14:49:05Z","started_at":"2026-04-26T13:10:02Z","closed_at":"2026-04-26T14:49:05Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-s1o","title":"viewer: extract inline JS from viewer.html into viewer.js","description":"viewer.html is ~1250 lines, almost entirely JavaScript. This makes it hard to edit with proper tooling (no syntax highlighting, linting, or go-to-definition). Extract the main viewer logic into a separate viewer.js file alongside viewer-url.js. The build.js step would need to copy it to the assets directory.","status":"closed","priority":4,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-25T23:16:36Z","created_by":"Bruno Postle","updated_at":"2026-04-26T14:49:05Z","started_at":"2026-04-26T13:10:02Z","closed_at":"2026-04-26T14:49:05Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-nd1","title":"Submit provisional IANA registration for ifc:// scheme","description":"Once the Phase 1 URL spec is stable, submit a provisional IANA URI scheme registration for ifc://.\\n\\nProcess: email iana@iana.org with scheme name, syntax description, security considerations, and a link to the spec (GitHub URL suffices). First Come First Served — no committee review, typically processed within days to weeks. See RFC 7595 for requirements.\\n\\nThis secures the namespace, establishes priority, and is a prerequisite if the scheme is ever proposed to buildingSMART as an open standard.","status":"open","priority":4,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-25T11:17:45Z","created_by":"Bruno Postle","updated_at":"2026-04-25T11:17:45Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-nd1","title":"Submit provisional IANA registration for ifc:// scheme","description":"Once the Phase 1 URL spec is stable, submit a provisional IANA URI scheme registration for ifc://.\\n\\nProcess: email iana@iana.org with scheme name, syntax description, security considerations, and a link to the spec (GitHub URL suffices). First Come First Served — no committee review, typically processed within days to weeks. See RFC 7595 for requirements.\\n\\nThis secures the namespace, establishes priority, and is a prerequisite if the scheme is ever proposed to buildingSMART as an open standard.","status":"open","priority":4,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-25T11:17:45Z","created_by":"Bruno Postle","updated_at":"2026-04-25T11:17:45Z","dependency_count":0,"dependent_count":0,"comment_count":0}
@ -112,5 +113,5 @@
{"_type":"issue","id":"ifcurl-vam","title":"Phase 6: Bonsai offer ifc:// URL when saving linked model reference","description":"When saving an IFCDOCUMENTREFERENCE in Bonsai, offer the option to write the location as an ifc:// URL rather than a relative path. When a relative path would traverse above the repository root, prompt the user to convert it to an ifc:// URL. Requires Phase 4 federation (ifcurl-bqt).","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:16Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:13Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-vam","depends_on_id":"ifcurl-bqt","type":"blocks","created_at":"2026-04-23T06:49:23Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-vam","title":"Phase 6: Bonsai offer ifc:// URL when saving linked model reference","description":"When saving an IFCDOCUMENTREFERENCE in Bonsai, offer the option to write the location as an ifc:// URL rather than a relative path. When a relative path would traverse above the repository root, prompt the user to convert it to an ifc:// URL. Requires Phase 4 federation (ifcurl-bqt).","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:16Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:13Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-vam","depends_on_id":"ifcurl-bqt","type":"blocks","created_at":"2026-04-23T06:49:23Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-9k2","title":"Phase 5: IFC Viewer integration (equivalent of Phase 4)","description":"Add ifc:// OS protocol handler and 'Copy view URL' button to the IFC Viewer desktop application, equivalent to the Bonsai Phase 4 integration. Depends on Phase 4 being complete as a reference implementation.","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:08Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:12Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-9k2","depends_on_id":"ifcurl-0oj","type":"blocks","created_at":"2026-04-23T06:49:14Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-9k2","title":"Phase 5: IFC Viewer integration (equivalent of Phase 4)","description":"Add ifc:// OS protocol handler and 'Copy view URL' button to the IFC Viewer desktop application, equivalent to the Bonsai Phase 4 integration. Depends on Phase 4 being complete as a reference implementation.","status":"deferred","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:49:08Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:15:12Z","defer_until":"2026-12-01T00:00:00Z","dependencies":[{"issue_id":"ifcurl-9k2","depends_on_id":"ifcurl-0oj","type":"blocks","created_at":"2026-04-23T06:49:14Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"ifcurl-prc","title":"Phase 3c: 3D diff view for IFC PR merges","description":"After a PR merge completes, surface a 'View merge in 3D' button using the Phase 3b viewer. Use @thatopen/components highlighter to colour added, removed, and modified elements differently, driven by comparing the merged IFC against either parent. Requires Phase 3b viewer (ifcurl-i1s) to be working.","status":"closed","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:30Z","created_by":"Bruno Postle","updated_at":"2026-04-26T17:15:07Z","closed_at":"2026-04-26T17:15:07Z","close_reason":"Rendered diff already implemented in footer.tmpl Case 3; static PNG via /render_diff endpoint, not interactive 3D","dependencies":[{"issue_id":"ifcurl-prc","depends_on_id":"ifcurl-i1s","type":"blocks","created_at":"2026-04-23T06:48:36Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"ifcurl-prc","title":"Phase 3c: 3D diff view for IFC PR merges","description":"After a PR merge completes, surface a 'View merge in 3D' button using the Phase 3b viewer. Use @thatopen/components highlighter to colour added, removed, and modified elements differently, driven by comparing the merged IFC against either parent. Requires Phase 3b viewer (ifcurl-i1s) to be working.","status":"closed","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:30Z","created_by":"Bruno Postle","updated_at":"2026-04-26T17:15:07Z","closed_at":"2026-04-26T17:15:07Z","close_reason":"Rendered diff already implemented in footer.tmpl Case 3; static PNG via /render_diff endpoint, not interactive 3D","dependencies":[{"issue_id":"ifcurl-prc","depends_on_id":"ifcurl-i1s","type":"blocks","created_at":"2026-04-23T06:48:36Z","created_by":"Claude","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"memory","key":"forgejo-build-and-deploy-procedure-go-build-c","value":"Forgejo build and deploy procedure: go build -C /home/bruno/src/forgejo -tags 'sqlite sqlite_unlock_notify' -ldflags \"-X 'forgejo.org/modules/setting.StaticRootPath=/usr/share/forgejo'\" -o /home/bruno/src/forgejo/forgejo . — then sudo cp forgejo /usr/bin/forgejo. StaticRootPath=/usr/share/forgejo. CustomPath=/var/lib/forgejo/custom. Custom templates go to /var/lib/forgejo/custom/templates/custom/ (e.g. footer.tmpl → /var/lib/forgejo/custom/templates/custom/footer.tmpl). Custom static files go to /var/lib/forgejo/custom/public/assets/ (NOT /etc/forgejo/public/assets/) and are served at /assets/*."}
{"_type":"memory","key":"torawurl-in-viewer-url-js-must-support-github","value":"toRawUrl in viewer-url.js must support GitHub, GitLab, Forgejo/Gitea (codeberg.org, self-hosted), and localhost. Tests in forgejo/tests/viewer-url.test.js cover all four. The localhost check (http vs https) is based on host.startsWith('localhost'), so subdomain.localhost gets https."} {"_type":"memory","key":"torawurl-in-viewer-url-js-must-support-github","value":"toRawUrl in viewer-url.js must support GitHub, GitLab, Forgejo/Gitea (codeberg.org, self-hosted), and localhost. Tests in forgejo/tests/viewer-url.test.js cover all four. The localhost check (http vs https) is based on host.startsWith('localhost'), so subdomain.localhost gets https."}
{"_type":"memory","key":"forgejo-build-and-deploy-procedure-go-build-c","value":"Forgejo build and deploy procedure: go build -C /home/bruno/src/forgejo -tags 'sqlite sqlite_unlock_notify' -ldflags \"-X 'forgejo.org/modules/setting.StaticRootPath=/usr/share/forgejo'\" -o /home/bruno/src/forgejo/forgejo . — then sudo cp forgejo /usr/bin/forgejo. StaticRootPath=/usr/share/forgejo. CustomPath=/var/lib/forgejo/custom. Custom templates go to /var/lib/forgejo/custom/templates/custom/ (e.g. footer.tmpl → /var/lib/forgejo/custom/templates/custom/footer.tmpl). Custom static files go to /var/lib/forgejo/custom/public/assets/ (NOT /etc/forgejo/public/assets/) and are served at /assets/*."}