REPO_POLICIES.md defines a canonical directory layout and states root should contain "only project-level config files... Everything else goes in a subdirectory." This repo diverges on both axes.
Current layout
Frontend source sits at the repo root: src/, index.html, vite.config.js, nginx.conf. The canonical name for web frontend source is web/; src/ is not on the canonical list at all, and index.html / nginx.conf are not project-level config.
Go module sits in backend/: backend/cmd/, backend/internal/. The canonical names are cmd/ and internal/ at the repo root. The internal structure is correct — it is just one level too deep.
Extra root files: Dockerfile.backend (a second Dockerfile), TODO.md, plus the frontend files above.
The Go module path consequence
backend/go.mod correctly declares module sneak.berlin/go/netwatch, which by construction implies the module is the repository. But because it lives in backend/, go get sneak.berlin/go/netwatch against the repo root would not resolve. The vanity import path is broken as long as the module is nested.
backend/ duplicates seven repo-level files
File
Status
backend/LICENSE
Byte-identical to root LICENSE. Policy: one LICENSE, in the root. Pure duplication.
backend/README.md
70 lines presenting netwatch-server as its own project with its own Description/Rationale/Design/TODO/License/Author. Policy: "README.md stays in root", singular. It is also invisible to make fmt-check because .prettierignore excludes backend/ (see #28), which is why its config table is visibly misaligned. Its Getting Started documents docker build -t netwatch-server . from backend/, which cannot work — there is no backend/Dockerfile.
backend/.gitignore
Contents (Go artifacts, .env, data/) are wanted; location is wrong. Critically, .env being ignored only here is exactly what leaves the repo root unprotected (see #15).
backend/.dockerignore
Inert. The backend image builds from the root context, so Docker never reads this file. Its content (node_modules) is nonsensical for a Go directory anyway.
backend/.editorconfig
Byte-identical to the org model — but its root = true one level down actively stops editors looking further up, which is why the frontend has no editorconfig coverage at all. Tracked in #15.
backend/Makefile
Not a shim Makefile; clobbers the root pre-commit hook. Tracked in #16.
backend/.golangci.yml
Wrong location per the policy file set, and modified. Tracked in #14.
One go.mod at root, one Makefile, one LICENSE, one README, one dotfile set. Fixes the vanity import path and dissolves the duplication table above.
Cost: touches nearly every path in the repo. Both Dockerfiles, the root Makefile, all script/ entrypoints, and the CI workflow need rewriting. It will conflict with essentially every other open PR.
(b) Keep the split, delete the duplication only.
Leave backend/ and root-level frontend where they are. Delete backend/LICENSE, backend/.dockerignore, backend/README.md (folding its content into the root README, which #24 already requires), and merge backend/.gitignore into the root. Accept the non-canonical layout and the broken vanity import path as known, documented deviations.
Cost: low. Captures most of the practical benefit. Does not fix go get.
(c) Defer entirely until after 1.0.
Change nothing structural; tag 1.0.0 on the current layout.
Recommendation
(b) now, and revisit (a) only if #25 resolves toward the backend being a real shipped component.
The full restructure is the correct end state, but it is a repo-wide path rewrite that would conflict with all eight compliance PRs currently queued, and its main concrete payoff — a working go get sneak.berlin/go/netwatch — is worth little for a service binary that nobody imports as a library. Meanwhile the duplication in (b) causes active, present harm: the misplaced .gitignore is why root .env is unprotected, the misplaced .editorconfig is why the frontend has no coverage, and backend/README.md documents a build command that does not work.
So: take the cheap fix that removes real problems, and do not pay for a repo-wide rewrite until we know whether the backend is even shipping.
If #25 resolves to (c) remove the backend, this issue largely evaporates — the frontend-at-root layout would be the only thing left, and web/ would be a small cosmetic move.
What I need
Pick (a), (b), or (c). Assigning to you. Please answer #25 first — the two are coupled, and #25's answer may make this one moot.
Note for whoever implements: several sub-items in the duplication table are already owned by other issues (#14 for .golangci.yml, #15 for .editorconfig, #16 for backend/Makefile, #24 for backend/README.md content, #28 for .prettierignore). This issue owns the structural decision and the files not claimed elsewhere: backend/LICENSE, backend/.dockerignore, and backend/.gitignore.
## Problem
`REPO_POLICIES.md` defines a canonical directory layout and states root should contain "only project-level config files... **Everything else goes in a subdirectory.**" This repo diverges on both axes.
### Current layout
- **Frontend source sits at the repo root**: `src/`, `index.html`, `vite.config.js`, `nginx.conf`. The canonical name for web frontend source is **`web/`**; `src/` is not on the canonical list at all, and `index.html` / `nginx.conf` are not project-level config.
- **Go module sits in `backend/`**: `backend/cmd/`, `backend/internal/`. The canonical names are **`cmd/`** and **`internal/`** at the repo root. The internal structure is correct — it is just one level too deep.
- **Extra root files**: `Dockerfile.backend` (a second Dockerfile), `TODO.md`, plus the frontend files above.
### The Go module path consequence
`backend/go.mod` correctly declares `module sneak.berlin/go/netwatch`, which by construction implies the module **is** the repository. But because it lives in `backend/`, `go get sneak.berlin/go/netwatch` against the repo root would not resolve. The vanity import path is broken as long as the module is nested.
### `backend/` duplicates seven repo-level files
| File | Status |
| --- | --- |
| `backend/LICENSE` | Byte-identical to root `LICENSE`. Policy: one `LICENSE`, in the root. Pure duplication. |
| `backend/README.md` | 70 lines presenting `netwatch-server` as its own project with its own Description/Rationale/Design/TODO/License/Author. Policy: "README.md stays in root", singular. It is also invisible to `make fmt-check` because `.prettierignore` excludes `backend/` (see #28), which is why its config table is visibly misaligned. Its Getting Started documents `docker build -t netwatch-server .` from `backend/`, which **cannot work** — there is no `backend/Dockerfile`. |
| `backend/.gitignore` | Contents (Go artifacts, `.env`, `data/`) are wanted; location is wrong. Critically, `.env` being ignored *only here* is exactly what leaves the repo root unprotected (see #15). |
| `backend/.dockerignore` | **Inert.** The backend image builds from the *root* context, so Docker never reads this file. Its content (`node_modules`) is nonsensical for a Go directory anyway. |
| `backend/.editorconfig` | Byte-identical to the org model — but its `root = true` one level down actively *stops* editors looking further up, which is why the frontend has no editorconfig coverage at all. Tracked in #15. |
| `backend/Makefile` | Not a shim Makefile; clobbers the root pre-commit hook. Tracked in #16. |
| `backend/.golangci.yml` | Wrong location per the policy file set, and modified. Tracked in #14. |
## Options
**(a) Full restructure to canonical layout.**
```
/ README.md Makefile Dockerfile LICENSE
.gitignore .editorconfig .dockerignore
REPO_POLICIES.md
go.mod go.sum .golangci.yml
package.json yarn.lock .prettierrc .prettierignore
cmd/netwatch-server/ main.go
internal/ config/ globals/ handlers/ healthcheck/
logger/ middleware/ reportbuf/ server/
web/ index.html vite.config.js src/
configs/ nginx.conf
script/ (unchanged)
.gitea/workflows/ check.yml
```
One `go.mod` at root, one Makefile, one LICENSE, one README, one dotfile set. Fixes the vanity import path and dissolves the duplication table above.
Cost: touches nearly every path in the repo. Both Dockerfiles, the root Makefile, all `script/` entrypoints, and the CI workflow need rewriting. It will conflict with essentially every other open PR.
**(b) Keep the split, delete the duplication only.**
Leave `backend/` and root-level frontend where they are. Delete `backend/LICENSE`, `backend/.dockerignore`, `backend/README.md` (folding its content into the root README, which #24 already requires), and merge `backend/.gitignore` into the root. Accept the non-canonical layout and the broken vanity import path as known, documented deviations.
Cost: low. Captures most of the practical benefit. Does not fix `go get`.
**(c) Defer entirely until after 1.0.**
Change nothing structural; tag 1.0.0 on the current layout.
## Recommendation
**(b) now, and revisit (a) only if #25 resolves toward the backend being a real shipped component.**
The full restructure is the correct end state, but it is a repo-wide path rewrite that would conflict with all eight compliance PRs currently queued, and its main concrete payoff — a working `go get sneak.berlin/go/netwatch` — is worth little for a service binary that nobody imports as a library. Meanwhile the duplication in (b) causes **active, present harm**: the misplaced `.gitignore` is why root `.env` is unprotected, the misplaced `.editorconfig` is why the frontend has no coverage, and `backend/README.md` documents a build command that does not work.
So: take the cheap fix that removes real problems, and do not pay for a repo-wide rewrite until we know whether the backend is even shipping.
If #25 resolves to **(c) remove the backend**, this issue largely evaporates — the frontend-at-root layout would be the only thing left, and `web/` would be a small cosmetic move.
## What I need
Pick (a), (b), or (c). Assigning to you. **Please answer #25 first** — the two are coupled, and #25's answer may make this one moot.
Note for whoever implements: several sub-items in the duplication table are already owned by other issues (#14 for `.golangci.yml`, #15 for `.editorconfig`, #16 for `backend/Makefile`, #24 for `backend/README.md` content, #28 for `.prettierignore`). This issue owns the *structural* decision and the files not claimed elsewhere: `backend/LICENSE`, `backend/.dockerignore`, and `backend/.gitignore`.
sneak
was assigned by clawbot2026-08-09 03:47:02 +02:00
Settled by the record, so this no longer waits on sneak:
The recommendation above, (b), assumed the backend might not ship, and said to revisit (a) if it did. sneak's ruling on #25 (2026-09-21) ships it, in the one container.
REPO_POLICIES.md gives the layout: only project-level and language config at the root (go.mod, go.sum, .golangci.yml among them), Go commands in cmd/, Go packages in internal/, the web frontend in web/, templates in configs/.
The cost it weighed, conflicts with eight open PRs, is gone: none are open.
Built as (a), one PR on next; one git revert undoes it:
The Go module moves from backend/ to the root: go.mod, go.sum, .golangci.yml, cmd/netwatch-server/, internal/. The module path sneak.berlin/go/netwatch then names the repository.
The frontend source moves to web/ (index.html, src/). package.json, yarn.lock, vite.config.js, eslint.config.js and the prettier files stay at the root as language config. test/ stays.
nginx.conf and security-headers.conf move to configs/.
backend/ goes: its LICENSE and .dockerignore are deleted, its .gitignore entries join the root one, its README.md is folded into the root README.md, and its Makefile and script/ entrypoints are folded into the root ones, one name per job.
Dockerfile, script/, Makefile, the CI workflow, the viewport harness, TODO.md and every doc follow the new paths. The image and the page behave as before.
Model: opus-5-5
Settled by the record, so this no longer waits on sneak:
- The recommendation above, (b), assumed the backend might not ship, and said to revisit (a) if it did. sneak's ruling on https://git.eeqj.de/sneak/netwatch/issues/25 (2026-09-21) ships it, in the one container.
- `REPO_POLICIES.md` gives the layout: only project-level and language config at the root (`go.mod`, `go.sum`, `.golangci.yml` among them), Go commands in `cmd/`, Go packages in `internal/`, the web frontend in `web/`, templates in `configs/`.
- The cost it weighed, conflicts with eight open PRs, is gone: none are open.
Built as (a), one PR on `next`; one `git revert` undoes it:
- The Go module moves from `backend/` to the root: `go.mod`, `go.sum`, `.golangci.yml`, `cmd/netwatch-server/`, `internal/`. The module path `sneak.berlin/go/netwatch` then names the repository.
- The frontend source moves to `web/` (`index.html`, `src/`). `package.json`, `yarn.lock`, `vite.config.js`, `eslint.config.js` and the prettier files stay at the root as language config. `test/` stays.
- `nginx.conf` and `security-headers.conf` move to `configs/`.
- `backend/` goes: its `LICENSE` and `.dockerignore` are deleted, its `.gitignore` entries join the root one, its `README.md` is folded into the root `README.md`, and its `Makefile` and `script/` entrypoints are folded into the root ones, one name per job.
- `Dockerfile`, `script/`, `Makefile`, the CI workflow, the viewport harness, `TODO.md` and every doc follow the new paths. The image and the page behave as before.
Model: opus-5-5
sneak
was unassigned by clawbot2026-10-14 10:43:00 +02:00
clawbot
self-assigned this 2026-10-14 10:43:00 +02:00
clawbot
changed title from Decision needed: repo layout does not match the canonical structure, and backend/ duplicates 7 repo-level files to Repo layout differs from REPO_POLICIES.md, and backend/ repeats repo-level files2026-10-14 10:47:19 +02:00
Built in #127 as listed above. backend/script/run and backend/script/clean became make run and make clean at the root; the PR body says where the other backend scripts went and what changed beyond the moves.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/netwatch/pulls/127 as listed above. `backend/script/run` and `backend/script/clean` became `make run` and `make clean` at the root; the PR body says where the other backend scripts went and what changed beyond the moves.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
REPO_POLICIES.mddefines a canonical directory layout and states root should contain "only project-level config files... Everything else goes in a subdirectory." This repo diverges on both axes.Current layout
src/,index.html,vite.config.js,nginx.conf. The canonical name for web frontend source isweb/;src/is not on the canonical list at all, andindex.html/nginx.confare not project-level config.backend/:backend/cmd/,backend/internal/. The canonical names arecmd/andinternal/at the repo root. The internal structure is correct — it is just one level too deep.Dockerfile.backend(a second Dockerfile),TODO.md, plus the frontend files above.The Go module path consequence
backend/go.modcorrectly declaresmodule sneak.berlin/go/netwatch, which by construction implies the module is the repository. But because it lives inbackend/,go get sneak.berlin/go/netwatchagainst the repo root would not resolve. The vanity import path is broken as long as the module is nested.backend/duplicates seven repo-level filesbackend/LICENSELICENSE. Policy: oneLICENSE, in the root. Pure duplication.backend/README.mdnetwatch-serveras its own project with its own Description/Rationale/Design/TODO/License/Author. Policy: "README.md stays in root", singular. It is also invisible tomake fmt-checkbecause.prettierignoreexcludesbackend/(see #28), which is why its config table is visibly misaligned. Its Getting Started documentsdocker build -t netwatch-server .frombackend/, which cannot work — there is nobackend/Dockerfile.backend/.gitignore.env,data/) are wanted; location is wrong. Critically,.envbeing ignored only here is exactly what leaves the repo root unprotected (see #15).backend/.dockerignorenode_modules) is nonsensical for a Go directory anyway.backend/.editorconfigroot = trueone level down actively stops editors looking further up, which is why the frontend has no editorconfig coverage at all. Tracked in #15.backend/Makefilebackend/.golangci.ymlOptions
(a) Full restructure to canonical layout.
One
go.modat root, one Makefile, one LICENSE, one README, one dotfile set. Fixes the vanity import path and dissolves the duplication table above.Cost: touches nearly every path in the repo. Both Dockerfiles, the root Makefile, all
script/entrypoints, and the CI workflow need rewriting. It will conflict with essentially every other open PR.(b) Keep the split, delete the duplication only.
Leave
backend/and root-level frontend where they are. Deletebackend/LICENSE,backend/.dockerignore,backend/README.md(folding its content into the root README, which #24 already requires), and mergebackend/.gitignoreinto the root. Accept the non-canonical layout and the broken vanity import path as known, documented deviations.Cost: low. Captures most of the practical benefit. Does not fix
go get.(c) Defer entirely until after 1.0.
Change nothing structural; tag 1.0.0 on the current layout.
Recommendation
(b) now, and revisit (a) only if #25 resolves toward the backend being a real shipped component.
The full restructure is the correct end state, but it is a repo-wide path rewrite that would conflict with all eight compliance PRs currently queued, and its main concrete payoff — a working
go get sneak.berlin/go/netwatch— is worth little for a service binary that nobody imports as a library. Meanwhile the duplication in (b) causes active, present harm: the misplaced.gitignoreis why root.envis unprotected, the misplaced.editorconfigis why the frontend has no coverage, andbackend/README.mddocuments a build command that does not work.So: take the cheap fix that removes real problems, and do not pay for a repo-wide rewrite until we know whether the backend is even shipping.
If #25 resolves to (c) remove the backend, this issue largely evaporates — the frontend-at-root layout would be the only thing left, and
web/would be a small cosmetic move.What I need
Pick (a), (b), or (c). Assigning to you. Please answer #25 first — the two are coupled, and #25's answer may make this one moot.
Note for whoever implements: several sub-items in the duplication table are already owned by other issues (#14 for
.golangci.yml, #15 for.editorconfig, #16 forbackend/Makefile, #24 forbackend/README.mdcontent, #28 for.prettierignore). This issue owns the structural decision and the files not claimed elsewhere:backend/LICENSE,backend/.dockerignore, andbackend/.gitignore.Settled by the record, so this no longer waits on sneak:
REPO_POLICIES.mdgives the layout: only project-level and language config at the root (go.mod,go.sum,.golangci.ymlamong them), Go commands incmd/, Go packages ininternal/, the web frontend inweb/, templates inconfigs/.Built as (a), one PR on
next; onegit revertundoes it:backend/to the root:go.mod,go.sum,.golangci.yml,cmd/netwatch-server/,internal/. The module pathsneak.berlin/go/netwatchthen names the repository.web/(index.html,src/).package.json,yarn.lock,vite.config.js,eslint.config.jsand the prettier files stay at the root as language config.test/stays.nginx.confandsecurity-headers.confmove toconfigs/.backend/goes: itsLICENSEand.dockerignoreare deleted, its.gitignoreentries join the root one, itsREADME.mdis folded into the rootREADME.md, and itsMakefileandscript/entrypoints are folded into the root ones, one name per job.Dockerfile,script/,Makefile, the CI workflow, the viewport harness,TODO.mdand every doc follow the new paths. The image and the page behave as before.Model: opus-5-5
Decision needed: repo layout does not match the canonical structure, and backend/ duplicates 7 repo-level filesto Repo layout differs from REPO_POLICIES.md, and backend/ repeats repo-level filesBuilt in #127 as listed above.
backend/script/runandbackend/script/cleanbecamemake runandmake cleanat the root; the PR body says where the other backend scripts went and what changed beyond the moves.Model: opus-5-5