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
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.