Skip to content

History

Revisions

  • wiki: rewrite the project tracker to the task-table standard

    @Pummelchen Pummelchen committed Sep 18, 2026
    9d2d5ca
  • Tracker: 10.8 is deployed — T-01 closed The live site now serves 10.8 with the city split in place, and the API was driven end to end over a kept-alive connection through Caddy. T-03 is the last row: a human with a WebGPU browser, after dark.

    @Pummelchen Pummelchen committed Sep 18, 2026
    a1534ea
  • Docs: the suite is 41 files / 2405 checks, and releases are a thing now Architecture and Development still quoted 29 files and 1932 checks. It also had no release section, so it now says what release.sh does, why a release is a source archive rather than a build, and that the first one is v10.8.

    @Pummelchen Pummelchen committed Sep 18, 2026
    04484d5
  • Tracker: T-01 is down to SSH access main carries the work and CI is green on it, so the only thing between the repo and production is that root@91.99.176.243 refuses the only key here. Records the exact public key to authorize and the command to run instead.

    @Pummelchen Pummelchen committed Sep 18, 2026
    12d7ea4
  • Tracker: T-02, T-04 and T-05 are done; one deploy and one browser check left T-02, T-04 and T-05 closed, so their rows are gone: a number is never reused, so the gaps are the record that they are done. What is left is the two things only a human can do — the 10.8 deploy (which now also has to sync the new roomcad_api/ package, or the entry point arrives with nothing to import) and an actual look at the 3D in a WebGPU browser after dark. The gate figure is now 41 files and 2405 checks. T-01 also records what was verified without touching the host, so whoever runs the deploy knows the artifacts are already known good rather than untested.

    @Pummelchen Pummelchen committed Sep 18, 2026
    e83808c
  • Tracker: open work only, one numbered row per item Reduce the tracker to what is outstanding: open work and open decisions, in one table with a sequential task number. Removed the rows that are not open work — the Won't-fix decisions (D1-D7, D9) and the Reference notes (N1-N6) — along with the prose that only described state. They remain in this wiki's git history, which is the same place completed work already lives; code-level traps belong to AGENTS.md, as the header says. Kept and refreshed the three items that are still outstanding (the pending 10.8 deploy, the two unsplit large modules, and looking at the 3D in a real WebGPU browser), updated the gate figure to the current suite (41 files, 2401 checks), and added the two open decisions surfaced by the pre-production audit: how autoLayoutRooms should treat a piece with no door frontage, and whether the city's vehicle lamps should follow the time of day.

    @Pummelchen Pummelchen committed Sep 18, 2026
    660dfce
  • Tracker: five of seven splits done styles.css, store.js, app.js, editor2d.js and walk3d.js are split; city.js and server.py remain. Each split was verified against the same check count as before it, which is the evidence that it was a move rather than a rewrite. The row also records a caveat rather than hiding it: the walk3d.js commit was verified by --fast plus a hand check of every constant the skipped fuzz files grep out of the walk3d source, but the four slow fuzz files had not re-run against it when work stopped. ./tests/run.sh should be run before the next release.

    @Pummelchen Pummelchen committed Sep 17, 2026
    61ae976
  • Tracker: app.js is split; four files remain in T17 styles.css, store.js and app.js are done, each verified by the full suite at the same check count as before the split — which is the evidence that a split was a move rather than a rewrite. app.js was the awkward one and the row now says why: a script wired by ordered side effects, ten tests grepping its source, three lifting fragments with new Function, and five module-level lets written from two or three sections at once. The last of those is the interesting one — an imported binding cannot be assigned to, so shared mutable state had to become a property of one appState object rather than five scattered lets. Remaining: editor2d.js, walk3d.js, city.js (one class, 123 methods, shared instance state) and server.py, which is last because it is the only one coupled to the deploy.

    @Pummelchen Pummelchen committed Sep 17, 2026
    7a6b06a
  • Tracker: store.js is split; app.js is next and is the awkward one store.js is a facade over six files composed with Object.assign. All 78 methods are present exactly once — checked against the original with brace-aware extraction, because a duplicate name would silently win with no error and no test that names it. The interesting failure was live-multi: it stood five separate clients up by importing store.js under five query strings, which stopped being five separate people the moment store.js became a facade. The query string gave a new facade while the state stayed the one instance, so all five shared a room. One check of forty-four failed, and the other forty-three went on passing. createStore() now says what it means. app.js is next and needs care for three separate reasons, all of which the row records: it is a script wired by ordered side effects, ten tests grep its source, and app-internals lifts fragments with new Function. The package-source helper landed before the split so the tests could keep asking about the real code.

    @Pummelchen Pummelchen committed Sep 17, 2026
    449a6f2
  • Tracker: T17 has started — styles.css is split and the other six are ordered styles.css is six sheets under roomcad/web/styles/, cut at the section markers rather than grouped into tidier files, because the link order is now part of the cascade: a rule in a later sheet wins a specificity tie exactly as it used to win by coming later in the one file. Reordering the links, or moving a rule between sheets out of order, changes which rule wins and nothing reports it. The split was verified byte-for-byte against the pre-split file — all 25931 bytes — and is held permanently by tests/styles-split.test.mjs as 'no rule was lost' rather than 'nothing changed', because the second fails on the next legitimate edit. A gate that has to be edited away is one nobody trusts. The row now lists the remaining six in the order they will be taken, with the reason server.py is last.

    @Pummelchen Pummelchen committed Sep 17, 2026
    bee62b4
  • Tracker: T16 closed — a repaired load reports what it cost T16's decision was 'report it', and it is built: sanitize() returns what it dropped and repaired, the three load paths say so, and a drop raises a toast. The row is gone, the gate figure is 34 files and 2026 checks, and the version line now distinguishes the repository (10.8) from the live site (10.7 until someone deploys) — which they have never been before, and will not be again after the next deploy. 16 rows: 1 Open, 8 Won't fix, 1 Waiting, 6 Reference.

    @Pummelchen Pummelchen committed Sep 17, 2026
    a4b20d1
  • T16: record the owner's decision — a repaired load must say so The question was whether a load that had to repair the document should tell the user. Answer: yes. The row keeps what it will take, so it is a decision with a plan rather than a question that has been asked twice. A plan that quietly lost a 12 cm wall is a plan the user believes is intact, and that is the failure a repair pass must not have. It is user-facing, so it carries a version bump.

    @Pummelchen Pummelchen committed Sep 17, 2026
    80501d1
  • Tracker: T12-T15 closed, and the decisions they pointed at corrected Four test gaps are closed, so their rows are gone and the decisions behind them now name the tests that hold them. D2 was wrong about its own subject. It said walk3d.js's non-axis collider branch was "left in place deliberately ... the collider's own guard against a wall it cannot represent". It was not a guard: it was an assumption that anything not horizontal is vertical, and for any other angle it put the box in the wrong place. The collider is now oriented to the wall, so D2 records what is actually left deliberately — the two axis-aligned cases, unrotated, because rotating them would change the geometry of every wall in every room for no gain. D8 rested on a false premise and is gone. "The vendored Rapier build carries no version string" is not true: the export identifier is minified, the value it returns is not, and RAPIER.version() answers 0.20.0. N6 records that, and the SHA-256 table that now pins every file under lib/. D1 and D3 keep their decisions and gain the test that defends them. 17 rows: 2 Open, 8 Won't fix, 1 Waiting, 6 Reference.

    @Pummelchen Pummelchen committed Sep 17, 2026
    e227f9f
  • Tracker: the model split, and what is left of the 500-line guideline Task 9 of the cleanup. T17 records the seven modules still over the guideline and why each is left: city.js is one class with 123 methods sharing instance state, and walk3d, editor2d, store and app are the same shape, so splitting them is a refactor of shared state rather than the move plan.js allowed. server.py is also tied to the deploy — deploy.sh copies that one file and the unit runs it — so a package means changing the deploy, the unit and the docs together. D9 records autoLayoutRooms as a deliberate exception: one 585-line algorithm whose phases and inner helpers share closure state, which is why plan/layout.js is the one module still over. N5 notes that plan.js is a facade now, so a source contract has to read the whole package. 21 rows: 6 Open, 9 Won't fix, 1 Waiting, 5 Reference.

    @Pummelchen Pummelchen committed Sep 17, 2026
    ab6969d
  • Wiki: a user guide with a worked example, not a history of the repository Task 4 and 6 of the cleanup. The tracker had 73 rows and 55 of them were finished work. That made it a history of the development, which is what git is for. The closed rows are gone; what is left is one table of 18 — the 5 open items, the 8 deliberate decisions, the one thing waiting on a human, and the 4 notes that are easy to get wrong twice. A line at the top says where the completed work went, so the emptiness reads as a decision rather than as an oversight. Home is a landing page now: the live URL first, then a six-step "try it in sixty seconds" example with what each step gives you, then navigation, then how to run it locally. The sidebar carries the live link on every page. Architecture and Development was the one page that was about the repository rather than about using RoomCAD — module line counts, design-decision narratives, and a second copy of rules that already live in AGENTS.md. It is now how to run it, how to run the tests, a one-line map of the modules, and a pointer to AGENTS.md and RELEASE.md as the single source. Repeated rules drift; the copy in the wiki is the one nobody updates. Verified: every internal wiki link resolves, no page is orphaned, every page is reachable from the sidebar, and no page claims the tracker shows finished work.

    @Pummelchen Pummelchen committed Sep 17, 2026
    a824266
  • Tracker: one table, one row per item The tracker had grown six different shapes for the same thing — a status table, four "Done" tables grouped by area, an "Open — bugs" table that repeated B1-B4 already listed above it, an "Open — tasks" table, a "Known and deliberate" list, a "Waiting on a human" section and a deploy log. Reading it meant knowing which section a thing would be in. It is now one table of 73 rows with four columns: ID, item, status, outcome. The ID prefix says what kind it is (A audit, B bug, T task, D deliberate, H needs a human, N note), so kind and status are separate facts rather than the same one twice. Nothing was dropped, and two things were added that only existed elsewhere: - the guard-check caveat now has a row (N1). It was in the d0c640e commit message — "the 10 acceptance guards in server-live.test.py ... exist to catch a regression in the fix, not to detect the absent feature" — which is not where anyone reading the tracker would find it. This is the row I told the user was in the tracker and was not. - the deploy rehearsal became its own row (T18) rather than being folded into the deploy. Rehearsing is what de-risked the first run of the hardened unit, and the evidence (the 401 → login → rooms → save round trip, the WAL permission failure it reproduced, the same-origin header shapes) was worth keeping. Also fixed: the T3 and T8 rows had run together on one line with no newline, so T8 did not render as a row at all. The five Open rows are the actionable remainder found while auditing the tracker itself: tests for the strict furniture helpers, the non-axis collider branch and Walk3D.dispose(); a hash to pin the unversioned vendored Rapier build; and a decision on whether sanitize() should report what it repaired.

    @Pummelchen Pummelchen committed Sep 17, 2026
    e5deb10
  • Tracker: 10.7 is deployed to production The hardened unit runs the API as roomcadapp inside the sandbox (5.3 MEDIUM, from 9.4 UNSAFE as root). Backed up the live database first with sqlite3 .backup — most of its data was still only in the -wal file, so a cp would have been wrong — and verified afterwards: 10.7 served, the directory and all three database files owned by the service user, data intact at 35 rows, GET / 200, /api/rooms 401 unauthenticated, the legacy :8443 links still answering, a real login through the public URL returning the room list, and an authenticated live stream opening with 200 text/event-stream. What is left is not code: the 3D fixes still want a look in a WebGPU browser, because nothing in the repository renders the scene.

    @Pummelchen Pummelchen committed Sep 16, 2026
    23b10a8
  • Tracker: the same-origin check verified against production's own Origin/Host shapes The 8443 entry point is kept for legacy links, and it only keeps working because the master Caddy forwards Host verbatim (header_up Host {host}) — so the check was run with the exact shapes: 443 without ports, 8443 with the port on both sides, 8443 with the port stripped from Host (refused, correctly), a cross-site origin (refused), and no Origin at all (allowed, which is what curl and the suite send).

    @Pummelchen Pummelchen committed Sep 16, 2026
    af3bf20
  • Tracker: the deploy path is rehearsed — the hardened unit runs, reads and writes Production could not be touched, so the hardened unit was stood up in a scratch directory against a copy of the live database, under the same sandbox directives, as an unprivileged user. It started, refused an unauthenticated call, accepted a login, read the live rooms and saved one. It also demonstrated the failure it prevents: a root-owned /var/roomcad kills the app on PRAGMA journal_mode=WAL, which is why deploy.sh chowns the directory itself.

    @Pummelchen Pummelchen committed Sep 16, 2026
    d8bc410
  • Tracker + architecture: T2 closed — the app's buttons and the inspector actions are driven

    @Pummelchen Pummelchen committed Sep 16, 2026
    0b945da
  • Tracker: name the exact blocker left in T2 (no HTML parsing in the stub, not just no selector engine)

    @Pummelchen Pummelchen committed Sep 16, 2026
    c0c84fb
  • Tracker: app.js can be imported now, and T2 is mostly closed The blocker T2 recorded — "app.js cannot be imported at all" — is gone. A module resolution hook applies the page's own import map to the whole graph, which rewriting import lines cannot do, because the vendored addons behind walk3d import the bare `three` themselves. So app-wiring.test.mjs boots the real app, lets it adopt the room the server names, fires its own document keydown handler to check command-Z reaches store.undo, and checks the live EventSource is opened. What is left of T2 is the click-driven half: the toolbar and inspector buttons. The stub DOM has no selector engine, so querySelectorAll returns nothing and a click cannot be aimed at a real button. A known, small gap with a named cause. Architecture also gained the resolver, the new test, and a correction — it still said app.js could not be imported at all.

    @Pummelchen Pummelchen committed Sep 16, 2026
    bd41f84
  • Tracker: the production-readiness pass — T1, T3-T11 closed, and B5 fixed Ten of the eleven open tasks are done and each row says what actually changed. T2 narrows to what is genuinely left: app.js's DOM event wiring and inspector rendering. The pure logic and the escaping boundary are covered now, and boot.test.mjs holds the ids the page has to provide. The pass also found a bug. Making the gate trustworthy meant seeding city-fuzz's traffic — it drove twenty cities with unseeded Math.random, which is why the full suite failed where the file alone passed — and hunting that drive turned up a bus leaving the city grid: a recorded junction decision held only a road INDEX, and an index is not a junction, so a decision to carry on through index 0 one way was still counted as a decision when the vehicle came back the other way, where there is no road. The record names the direction now, the stop-for-a-space path clears it, and _decideTurn refuses to act on a carry-on record where carrying on is not possible. Also recorded: the two traps this cost time to learn — a fresh query string does not re-evaluate an already-imported ES module (the first login test was silently inert because of it), and a test that configures its own preconditions can hide the bug it exists to catch. Three pages updated with the new facts: the stream caps and the same-origin check (Server API), the checksum verification and the narrow install default (Hosting), and the new tests plus the seeding rule (Architecture).

    @Pummelchen Pummelchen committed Sep 16, 2026
    f366b8e
  • Tracker: all four open bugs fixed; note the light limit and the new invariants B1-B4 are done, so the tracker's bug table is now a record of what each one actually did rather than a list of what is wrong, and the status line reads 0 open bugs. Every entry names the test that holds it. 3D Walkthrough said 'only the first 16 get one', which was true and was the bug: the pool was dealt out in plan order, so a particular lamp was dead for the life of the room. It now describes what happens instead — the nearest sixteen, and they follow you — and the 2D Editor Guide's note about lights points at it. Architecture and Development gains the invariants the fixes created: no shadow caster may hold a negative depth bias, the two wall-length floors are different rules, the light budget goes to what the viewer can see, and a plan too large to decompose reports it. Module line counts refreshed, including the two new test files.

    @Pummelchen Pummelchen committed Sep 16, 2026
    b442aa6
  • Resync the wiki with the code, and add a Project Tracker The wiki had not been touched since 2026-08-23, and 38 commits landed on the code after that. Some of what it said had been wrong for weeks. Hosting and Deployment was the worst of it: it documented an nginx :443 -> Caddy :8077 topology with certbot, a certificate hook and /etc/caddy paths. None of that has existed since RoomCAD moved behind the host's master Caddy — the real path is master Caddy -> RoomCAD's own Caddy on loopback :8081 -> server.py, with no certbot anywhere and the master answering ACME itself. It now describes the architecture that is actually deployed, the two service accounts, the systemd sandbox, and why deploy.sh chowns the database. Architecture and Development claimed city.js was ~630 lines (it is ~5200) and that app.js is the only module that touches the network (login.js does too, and plan.js/store.js do no I/O at all). It now has accurate sizes and module responsibilities, the test runner and CI, and the newer invariants — the sky dome must contain the walkable city, and frames must stop when the 3D view is not on screen. Server API and Storage gained the endpoint it was missing (/api/live-check), the baseSeq staleness rule, the JSON-object body requirement, and the note that rooms.db.sql is structure only. Troubleshooting and Live Collaboration lost their nginx instructions and gained the service-account failure mode and the two-file Caddy ownership. Project Tracker is new. There was no tracker anywhere — not in the wiki, not in issues (the repository has never had one), not in milestones. It records what this audit fixed, the 4 bugs and 11 tasks still open, and the handful of things that are deliberate and must not be 'fixed' by accident.

    @Pummelchen Pummelchen committed Sep 16, 2026
    495b376
  • Document the Rooms tool and SVG export Adds an evening-out section covering the gesture, what moves and what does not, and every reason the tool refuses. File Format gains the SVG export: what it contains, why it is sized in millimetres at a real architectural scale, and that it does not open back into RoomCAD.

    André Borchert committed Aug 22, 2026
    14b5266
  • The Room Name is the file name Getting Started now explains saving in those terms: name it, it appears in My Rooms at v0; save again for v1; rename and save to fork, leaving the original untouched. Notes how names become file names, including accent folding. Server API records that versions start at 0 and that the room list is newest first.

    André Borchert committed Aug 22, 2026
    1c97828
  • Document measuring, where walls may start, and the yellow overlap mark Adds a Measuring section covering why the line disappears, and records the two new wall rules: a wall must start on the building (hold to pan, click to fall back to Select), and a stretch where two same-axis walls double up is painted yellow rather than being prevented. Notes that corners and right-angle crossings are junctions, not overlaps.

    André Borchert committed Aug 22, 2026
    48f8eec
  • Furniture drags are not blocked any more Records the rule: a piece can be carried anywhere, including through a wall or onto another piece, and reads red until it fits. The red is a property of where the item is rather than a flash during the drag, so it persists and clears itself. Placing and nudging follow the same rule; the drawing canvas is the one hard limit.

    André Borchert committed Aug 22, 2026
    3253a8d
  • Document room area captions and public-area tiling Records where the m² caption comes from (the walls, not stored data), why a doorway does not merge two rooms, and that circulation is skipped. Adds the tiling rules for public areas: grid, flush snapping, trimming rather than stacking, and that they stay separate selectable objects.

    André Borchert committed Aug 22, 2026
    e3a12ef