e391f406e1
The artifacts pipeline carried the same weakness as the indexer walk, found while auditing for other instances of it. An `artifacts:` manifest entry resolves against the repository, but all three expansion branches reach the filesystem in a way that follows links — os.Stat for a literal path, filepath.Glob for a single-segment pattern, filepath.WalkDir for a recursive one. A link such as `docs/schema.sql -> /etc/shadow` therefore satisfied a manifest entry, and get_artifact returned its bytes verbatim: that handler read the file after resolveFilePath, which blocks lexical `../` traversal but happily follows a symlink, and it was the one content-serving handler that never applied the confinement check the others do. Glob expansion now refuses an escaping link in each branch, the read in materializeOne re-checks so an artifact list from a persisted index cannot reintroduce it, and get_artifact applies the same guard as every other tool that puts file content into a response.