id: db42bcef-a612-436f-9d14-72540f8acf0a title: 'Small robustness/consistency batch: ''.'' repo name, gitlink pages, inbox list escaping, content-type anchor, symlink gap' state: closed labels:
- polish assignees: [] milestone: null created: 2026-10-27T14:54:31.668727942Z updated: 2026-10-27T16:37:20.531268962Z
Smaller robustness/consistency items found in the same review. Each is independently shippable.
-
hu13 build .loses the repo name.resolve_repo_nameusesrepo.file_name(), which isNonefor".", so the site is titled "repo" instead of the directory name. Cosmetic, but.is the obvious invocation and it silently degrades the header. Fix: canonicalize (orrepo.absolutize) before takingfile_name, or fall back to the current dir name whenNone. -
Submodule (gitlink) entries render as a bogus file. A tree entry with mode
160000is not a blob;git show <branch>:<path>on it returns the commit object text, so the build writes:raw/vendor/dep=commit a5e5260…\nAuthor: …(looks like file content, is not)files/vendor/dep.html= a file page containing that text Fix: skip/detach gitlinks inls_tree(mark them), render a "submodule at <sha>" page, and never write them toraw/.
-
inbox listprints the id unescaped.cmd_listdoesprintln!("{} [{}] {} {}", e.id, escape_terminal(kind), …)— every other field goes throughescape_terminal,e.idcomes from the file stem. A*.jsonfile dropped/pulled into the inbox dir with a name containing ESC/control bytes prints raw ANSI.cmd_showescapes its id, so this is just an inconsistency: escape it too. -
content_type_formatchesends_with("/head"). That is any file namedheadanywhere in the tree, not just a bare repo'sHEAD. Anchor the rule to the real paths ("repo.git/HEAD","repo.git/info/refs","repo.git/info/packs","repo.git/packed-refs") or check the basename withPath::file_name(). -
Symlink handling is inconsistent across
.forge/readers.wikiskips symlinks explicitly andcollect_artifactsskips them, butforge::loadandreleases::loadfs::read_to_stringthe path directly, following symlinks. Today the content must still parse as frontmatter to reach output, so it is not an exploit — it is an invariant gap in the "never follow links out of the repo" rule. Make all four use oneread_repo_filehelper that rejects symlinks (and..components). -
--repo-name/name escaping is fine (verified: a directory named"><img src=x onerror=…>renders escaped in<title>/<h1>) — recording it here so future refactors keep it.
Acceptance:
-
hu13 build .titles the site with the directory name -
gitlink entries do not produce
raw/files -
inbox listescapes the id - content-type rule is path-anchored
- one symlink-rejecting reader shared by forge/releases/wiki/artifacts