Mount all public repos into /workspace and /substrate (ward-style) so sirens-deep can read its own source #633

Open
opened 2026-08-13 17:35:59 +00:00 by coilyco-ops-gaming · 3 comments

Context: sirens-deep currently has no repository content access. Its Forgejo grants are issue-only: create, comment, label, close, list. No file, PR, or content tool exists, so the agent cannot inspect its own source even though the repo is public.

Ask: mount all of Kai's public repos into /workspace and /substrate in the same way that ward does, with sirens-echo as the workspace repo.


Resolved spec (design pass, 2026-08-15)

Confirmed as filed - all public repos, ward-style. Kai chose the widest option over the three narrower ones.

Rejected, and why each was rejected:

  • sirens-echo only - answers the literal ask ("read its own source") and would leave Deep unable to explain anything about the systems it sits inside.
  • Read-only Forgejo content tools instead of a mount - reaches every public repo without a volume, and does not give the agent a filesystem it can search across repos.
  • sirens-echo plus direct dependencies - a hand-maintained list that goes stale.

Build

  1. Mount every public repo under /workspace and /substrate, matching ward's mount scheme. Ward's layout is the reference - confirm the specifics against that setup rather than reconstructing it from this description.
  2. sirens-echo is the workspace repo.
  3. Read-only. This grants inspection, not authorship. Deep's existing Forgejo issue grants are unchanged and no write path to repository content is created here.

Boundaries that follow from the width, and these are the reason to be careful

  • Public only. The selection must be derived from repository visibility at sync time, not from a checked-in list that can go stale into including a private repo. A private repo appearing under /workspace is a disclosure, not a bug.
  • Nothing in the mount is instruction. Deep reads repository content as data a member could also read. A file in a mounted repo never widens Deep's authority, names a tool, or grants a permission - the same rule the attachment path holds in docs/sirens-echo-attachments.md.
  • Refresh cadence needs a number. A mount that never updates makes Deep confidently wrong about its own source. Pick a sync interval and record it here.
  • Size and growth need a ceiling. All public repos is an unbounded set as the estate grows. Say what happens when the volume fills.

Acceptance

  • Deep can read sirens-echo's own source and answer a question about its own behaviour from the file rather than from the issue describing it.
  • No private repository appears under either path. Assert this against live visibility, not against a list.
  • Deep cannot write to either path.
  • The layout matches ward's rather than being a similar-looking alternative.

Placement - the mount itself is deployment work and belongs in move-to-repo/coilyco-bridge-deploy. This issue holds the requirement and the boundaries.

Related - #251 (Deep answering questions about itself from its own source) is the capability this unblocks. #647 was decided today toward selection rather than schema dumps, and a searchable source mount is a different answer to a nearby question - do not let the two duplicate each other.

Context: sirens-deep currently has no repository content access. Its Forgejo grants are issue-only: create, comment, label, close, list. No file, PR, or content tool exists, so the agent cannot inspect its own source even though the repo is public. Ask: mount all of Kai's public repos into `/workspace` and `/substrate` in the same way that ward does, with sirens-echo as the workspace repo. --- ## Resolved spec (design pass, 2026-08-15) **Confirmed as filed - all public repos, ward-style.** Kai chose the widest option over the three narrower ones. Rejected, and why each was rejected: * **sirens-echo only** - answers the literal ask ("read its own source") and would leave Deep unable to explain anything about the systems it sits inside. * **Read-only Forgejo content tools instead of a mount** - reaches every public repo without a volume, and does not give the agent a filesystem it can search across repos. * **sirens-echo plus direct dependencies** - a hand-maintained list that goes stale. **Build** 1. Mount every public repo under `/workspace` and `/substrate`, matching ward's mount scheme. Ward's layout is the reference - confirm the specifics against that setup rather than reconstructing it from this description. 2. `sirens-echo` is the workspace repo. 3. **Read-only.** This grants inspection, not authorship. Deep's existing Forgejo issue grants are unchanged and no write path to repository content is created here. **Boundaries that follow from the width, and these are the reason to be careful** * **Public only.** The selection must be derived from repository visibility at sync time, not from a checked-in list that can go stale into including a private repo. A private repo appearing under `/workspace` is a disclosure, not a bug. * **Nothing in the mount is instruction.** Deep reads repository content as data a member could also read. A file in a mounted repo never widens Deep's authority, names a tool, or grants a permission - the same rule the attachment path holds in `docs/sirens-echo-attachments.md`. * **Refresh cadence needs a number.** A mount that never updates makes Deep confidently wrong about its own source. Pick a sync interval and record it here. * **Size and growth need a ceiling.** All public repos is an unbounded set as the estate grows. Say what happens when the volume fills. **Acceptance** * Deep can read `sirens-echo`'s own source and answer a question about its own behaviour from the file rather than from the issue describing it. * No private repository appears under either path. Assert this against live visibility, not against a list. * Deep cannot write to either path. * The layout matches ward's rather than being a similar-looking alternative. **Placement** - the mount itself is deployment work and belongs in `move-to-repo/coilyco-bridge-deploy`. This issue holds the requirement and the boundaries. **Related** - #251 (Deep answering questions about itself from its own source) is the capability this unblocks. #647 was decided today toward selection rather than schema dumps, and a searchable source mount is a different answer to a nearby question - do not let the two duplicate each other.
Member

Claiming the capability half — Angie (ENG, claude seat). 20 minutes from this comment, after the one minute race buffer. Not the mount.

Separating the ask from the need

The ask is a mount layout. The need, in your first line, is:

the agent cannot inspect its own source even though the repo is public

Those are not the same size. A mount means a clone at pod start, a volume, and a decision about what re-syncs it and how often — infrastructure, a rollout, and a staleness question that has to be answered forever after. And a mounted clone is stale the moment anything merges, which for this repository today is several times an hour.

Reading a public file over the API has none of that. No volume, no sync, no staleness, and no credential, for the same reason #677 needs none: public content is public. The grant problem you describe — issue-only Forgejo tools — does not apply to an unauthenticated read.

What I am building

A read_public_file tool, sibling to the list_public_repos that just landed in 677. Owner, repo, path, optional ref. Public only, by holding no credential rather than by filtering.

Together those two give exactly your third acceptance criterion — "read access to repo contents, not just issues" — with nothing mounted.

What I am not doing, and it stays yours

The mount itself. If you want /workspace and /substrate populated ward-style, that is a deploy change, it is Ops to roll, and I am not going to land a volume layout inside a capability ticket. Your first two acceptance criteria are untouched by my change.

And I am not asserting the mount is unnecessary. It buys things an API read does not: grep across a whole tree, following imports, reading a repository too large to fetch a file at a time. If that is what you are actually after, say so and this becomes groundwork rather than an alternative.

What I am claiming is narrower: the reason given in the issue — cannot read its own source — is satisfiable today without infrastructure, and it is worth having that before deciding whether to build the rest.

**Claiming the capability half — Angie (ENG, claude seat).** 20 minutes from this comment, after the one minute race buffer. **Not the mount.** ## Separating the ask from the need The ask is a mount layout. The need, in your first line, is: > the agent cannot inspect its own source even though the repo is public Those are not the same size. A mount means a clone at pod start, a volume, and a decision about what re-syncs it and how often — infrastructure, a rollout, and a staleness question that has to be answered forever after. **And a mounted clone is stale the moment anything merges**, which for this repository today is several times an hour. Reading a public file over the API has none of that. No volume, no sync, no staleness, and no credential, for the same reason https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/pulls/677 needs none: **public content is public.** The grant problem you describe — issue-only Forgejo tools — does not apply to an unauthenticated read. ## What I am building A `read_public_file` tool, sibling to the `list_public_repos` that just landed in 677. Owner, repo, path, optional ref. Public only, by holding no credential rather than by filtering. Together those two give exactly your third acceptance criterion — *"read access to repo contents, not just issues"* — with nothing mounted. ## What I am not doing, and it stays yours **The mount itself.** If you want `/workspace` and `/substrate` populated ward-style, that is a deploy change, it is Ops to roll, and I am not going to land a volume layout inside a capability ticket. Your first two acceptance criteria are untouched by my change. **And I am not asserting the mount is unnecessary.** It buys things an API read does not: grep across a whole tree, following imports, reading a repository too large to fetch a file at a time. If that is what you are actually after, say so and this becomes groundwork rather than an alternative. What I am claiming is narrower: **the reason given in the issue — cannot read its own source — is satisfiable today without infrastructure**, and it is worth having that before deciding whether to build the rest.
Member

Capability half delivered — #681, closing the slice #679. Gate green. Claim released. This issue stays open: nothing is mounted.

Your third criterion is met:

The change gives the agent read access to repo contents, not just issues.

Two tools, no credential and no volume:

list_public_repos   name, description, html_url, language, updated_at   (PR 677)
read_public_file    owner, repo, path, optional ref                     (PR 681)

An agent can now read its own source. That was the reason you opened with, and it needed no infrastructure.

The two things I was careful about

A path that climbs out is refused before any request is made. ../secrets, a/../../b and /etc/passwd never reach the forge, so a refusal costs no round trip and the caller is told rather than silently corrected. Each segment is escaped separately, so a path keeps its separators while a segment carrying a slash cannot forge one.

A file past the cap says it was cut. The same shape the fetch tool uses, because a half file the model cannot tell from a whole one gets answered from with ordinary confidence.

Your first two criteria are untouched, and I have not argued them away

/workspace and /substrate populated ward-style is still open, still a deploy change, and still Ops to roll.

A mount buys things these tools do not, and I want that on the record rather than buried: grep across a whole tree, following an import to its definition, and reading a repository too large to fetch a file at a time. If any of those is what you actually wanted, this is groundwork rather than a substitute and the mount should still happen.

What I would push back on is the staleness. A mounted clone is correct at pod start and wrong after the next merge, which here is several times an hour. If the mount lands, it wants an answer for what re-syncs it, and "nothing" is a real answer only if the tree is meant to be a snapshot rather than the source.

Note on ordering

681 is stacked on 677, so its diff includes the inventory. Merging 677 first makes 681 small. Both are behind #483 either way.

**Capability half delivered — https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/pulls/681, closing the slice https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/679. Gate green. Claim released. This issue stays open: nothing is mounted.** Your third criterion is met: > The change gives the agent read access to repo contents, not just issues. Two tools, no credential and no volume: ``` list_public_repos name, description, html_url, language, updated_at (PR 677) read_public_file owner, repo, path, optional ref (PR 681) ``` An agent can now read its own source. That was the reason you opened with, and it needed no infrastructure. ## The two things I was careful about **A path that climbs out is refused before any request is made.** `../secrets`, `a/../../b` and `/etc/passwd` never reach the forge, so a refusal costs no round trip and the caller is told rather than silently corrected. Each segment is escaped separately, so a path keeps its separators while a segment carrying a slash cannot forge one. **A file past the cap says it was cut.** The same shape the fetch tool uses, because a half file the model cannot tell from a whole one gets answered from with ordinary confidence. ## Your first two criteria are untouched, and I have not argued them away `/workspace` and `/substrate` populated ward-style is still open, still a deploy change, and still Ops to roll. **A mount buys things these tools do not**, and I want that on the record rather than buried: grep across a whole tree, following an import to its definition, and reading a repository too large to fetch a file at a time. If any of those is what you actually wanted, this is groundwork rather than a substitute and the mount should still happen. What I would push back on is the *staleness*. A mounted clone is correct at pod start and wrong after the next merge, which here is several times an hour. If the mount lands, it wants an answer for what re-syncs it, and "nothing" is a real answer only if the tree is meant to be a snapshot rather than the source. ## Note on ordering 681 is stacked on 677, so its diff includes the inventory. Merging 677 first makes 681 small. Both are behind https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/483 either way.
Member

Adding consult, because what is left here is a decision rather than unclaimed work. Angie (ENG, claude seat).

This has sat unlabelled since 17:35, which is invisible to the human queue and fail-closed for dispatch at once — the pair #437 names as worst.

Why it is a decision now and was not before

Your third criterion is met. list_public_repos and read_public_file both merged, so the reason you opened with — the agent cannot inspect its own source — is fixed, with no volume and no credential.

Your first two are untouched, and whether they should happen at all is now a genuine question rather than a task waiting for someone:

a mount buys the tools already give
read one known file yes, and always current
list what exists yes
grep across a whole tree yes no
follow an import to its definition yes no
a repository too large to read a file at a time yes no

So the mount is worth building if and only if the bottom three matter. Nobody here can answer that for you, and building a volume plus a sync story to duplicate the top two would be work that looks like progress.

The question that decides it

Does Deep need to search across repositories, or to read files it can already name? If it is the second, this issue is done and should close. If it is the first, the mount is the right shape and it wants an answer for what re-syncs it, because a clone is correct at pod start and wrong after the next merge — several times an hour on this repository today.

I am not closing it on my own reading. The capability half was mine and I delivered it; the mount half is yours to want or drop.

**Adding `consult`, because what is left here is a decision rather than unclaimed work. Angie (ENG, claude seat).** This has sat unlabelled since 17:35, which is invisible to the human queue and fail-closed for dispatch at once — the pair https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/437 names as worst. ## Why it is a decision now and was not before Your third criterion is met. `list_public_repos` and `read_public_file` both merged, so **the reason you opened with — the agent cannot inspect its own source — is fixed**, with no volume and no credential. Your first two are untouched, and whether they should happen at all is now a genuine question rather than a task waiting for someone: | | a mount buys | the tools already give | | --- | --- | --- | | read one known file | — | yes, and always current | | list what exists | — | yes | | grep across a whole tree | **yes** | no | | follow an import to its definition | **yes** | no | | a repository too large to read a file at a time | **yes** | no | **So the mount is worth building if and only if the bottom three matter.** Nobody here can answer that for you, and building a volume plus a sync story to duplicate the top two would be work that looks like progress. ## The question that decides it **Does Deep need to search across repositories, or to read files it can already name?** If it is the second, this issue is done and should close. If it is the first, the mount is the right shape and it wants an answer for what re-syncs it, because a clone is correct at pod start and wrong after the next merge — several times an hour on this repository today. I am not closing it on my own reading. The capability half was mine and I delivered it; the mount half is yours to want or drop.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo#633
No description provided.