Skip to content

Public pass: HOME in the image, drop the pre-release framing, add the repo furniture - #10

Merged
ryanlitalien merged 2 commits into
mainfrom
release/public-pass
Sep 9, 2026
Merged

ryanlitalien merged 2 commits into
mainfrom
release/public-pass

Conversation

@ryanlitalien

@ryanlitalien ryanlitalien commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

A public pass on the repo now that the Perforce path runs in production. Two commits: one code fix and the docs that were still describing a spike, then the repo furniture the repo never had.

1. HOME is load-bearing and the image never set it

The daemon passes HOME straight through to p4 (internal/tools/perforce.go, env()), and p4 reads $HOME/.p4trust and $HOME/.p4tickets. The image sets WORKDIR /home/connector but no ENV HOME, so p4 receives an empty HOME, never consults the trust file, and every p4.* verb fails against an SSL-enabled p4d with perforce: exit status 1, even when the trust file is mounted correctly.

The first studio deployment hit exactly this and worked around it with a compose-level HOME: env var. That belongs in the image so nobody else has to rediscover it. Set on both the runtime and uat stages, so moving a deployment between the two still changes only the digest.

Verified on a local build of the runtime target: docker image inspect now reports HOME=/home/connector alongside PATH and SSL_CERT_FILE, user still 10001:10001.

2. The docs still described a day-1 spike

The Perforce path now runs in production: a real changelist travelled from a studio's own Helix Core server, through the connector on the studio's box, over one outbound TLS connection to the broker, and was recorded on a ButterStack project. The docs had not caught up.

  • README drops Status: pre-release and the link to a tracking issue in a private repo (a 404 for every public reader), and says what is actually proven instead.
  • PROTOCOL.md is v0, the protocol the shipped connector speaks, rather than a schema waiting for a server half. The "does not describe an endpoint that exists" paragraph is gone, because the endpoint exists. The tenant-context drill pointer now points at design-notes instead of a README section that moved.
  • docs/design-notes.md turns "What the spike does not prove" into "What is not yet proven", moves the items production closed out into a short "proven since" note, and keeps the honest remainder: the seven drills have no production-side result, TeamCity stays off until a connector-scoped credential exists, home-connection latency, Sigstore signing and egress.md, scale and multi-node routing, and everything beyond the five compiled verbs.

3. Repo furniture

The repo had a LICENSE and nothing else. Every sibling public repo carries CONTRIBUTING.md and issue templates, and the two that handle credentials carry SECURITY.md. This one handles credentials more directly than any of them and had no private disclosure path at all, so a reporter's only option was a public issue.

  • SECURITY.md is written around the daemon's four standing claims (outbound only, the allowlist is the boundary, credentials stay local, the broker cannot reconfigure the connector), so a reporter can tell whether what they found is in scope. It also says what is not a security issue, since a reserved verb returning a denial and a hard startup failure on a bad config both look alarming from outside and are both working as designed.
  • CONTRIBUTING.md leads with the constraint that actually governs changes here: the vocabulary is the security boundary, argument constraints are schema, and a denial path with no drill is an untested security claim.
  • Issue templates for bug and feature, plus a config.yml that routes security reports to SECURITY.md before someone files one publicly. The bug template asks for the connector log and a redacted connector.yml, and warns before the paste rather than after.

Two accuracy fixes found while writing those:

  • README asked for Go 1.25 to build from source; the module's own go directive is 1.23. Release builds do use 1.25, so both numbers are now stated for what each one is.
  • make check already runs test and drills, so telling contributors to run them separately was wrong.

Done outside this PR (repo settings, no diff)

  • Description rewritten to drop "Pre-release."
  • Homepage set to butterstack.com and topics added, matching the sibling public repos.
  • Secret scanning and push protection enabled; Dependabot security updates enabled.
  • Confirmed ghcr.io/butterstack/butterstack-connector:v0.2.0 pulls anonymously (HTTP 200 on the manifest with an anonymous ghcr token), so the README's install instructions work for a stranger.

After merge

Releases here are tag-driven (on: push: tags: ["v*"]); merging to main publishes nothing. Tag v0.2.1 so the published image carries the HOME fix, then bump the docker run example in the README to that tag.

No Go code changed; go build ./... is green and the runtime image builds.

Two things, both surfaced by the first production deployment.

HOME is load-bearing and the image never set it. The daemon passes
HOME straight through to `p4`, which reads $HOME/.p4trust and
$HOME/.p4tickets. With HOME empty, p4 never finds the trust file and
every p4.* verb fails against an SSL-enabled p4d with `exit status 1`,
even when the mount is correct. The first studio deployment hit this
and worked around it with a compose-level `HOME:` env var; that
belongs in the image, so nobody else has to rediscover it. Set on
both the runtime and uat stages, so moving between them still changes
only the digest.

The docs still described a day-1 spike against a mock broker. The
Perforce path now runs in production: a real changelist travelled from
a studio's own Helix Core, through the connector, over one outbound
TLS connection to the broker, and was recorded on a ButterStack
project. So:

- README drops "Status: pre-release" and the link to a tracking issue
  in a private repo (a 404 for every public reader), and says what is
  actually proven.
- PROTOCOL.md is v0, the protocol the shipped connector speaks, not a
  schema waiting for a server half. The server half exists.
- design-notes.md's "What the spike does not prove" becomes "What is
  not yet proven", with the items production closed out moved into a
  "proven since" note and the honest remainder kept: the drills have
  no production-side result, TeamCity is off until a connector-scoped
  credential exists, home-connection latency, Sigstore signing and
  egress.md, scale and multi-node routing, and the uncompiled verbs.
The repo had a LICENSE and nothing else. Every sibling public repo
(butterstack-cli, butterstack-mcp, gamedev-agents, perforce-docker)
carries CONTRIBUTING.md and issue templates, and the two that handle
credentials carry SECURITY.md. This one handles credentials more
directly than any of them and had no disclosure path at all, so a
reporter's only option was a public issue.

SECURITY.md is written around the daemon's four standing claims
(outbound only, the allowlist is the boundary, credentials stay local,
the broker cannot reconfigure the connector), so a reporter can tell
whether what they found is in scope. It also says what is not a
security issue, since a reserved verb returning a denial and a hard
startup failure on a bad config are both working as designed and both
look alarming from the outside.

CONTRIBUTING.md leads with the constraint that actually governs
changes here: the vocabulary is the security boundary, argument
constraints are schema, and a denial path with no drill is an
untested security claim.

The bug template asks for the connector log and a redacted
connector.yml, and warns before the paste rather than after.

Two accuracy fixes found while writing these:

- README asked for Go 1.25 to build from source; the module's own `go`
  directive is 1.23. Release builds do use 1.25, so both numbers are
  now stated for what each one is.
- `make check` already runs both test and drills, so telling
  contributors to run them separately was wrong.
@ryanlitalien ryanlitalien changed the title release: set HOME in the image, and drop the pre-release framing Public pass: HOME in the image, drop the pre-release framing, add the repo furniture Sep 9, 2026
@ryanlitalien
ryanlitalien merged commit 628034c into main Sep 9, 2026
1 check passed
@ryanlitalien
ryanlitalien deleted the release/public-pass branch September 9, 2026 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant