Skip to content

Stop publishing THEOREM_GIT_TOKEN in build logs; raise the gulp heap - #182

Merged
Travis-Gilbert merged 1 commit into
mainfrom
fix/studio-token-and-heap
Aug 4, 2026
Merged

Stop publishing THEOREM_GIT_TOKEN in build logs; raise the gulp heap#182
Travis-Gilbert merged 1 commit into
mainfrom
fix/studio-token-and-heap

Conversation

@Travis-Gilbert

Copy link
Copy Markdown
Owner

Two findings from deploy 39ea1ed3, the first build that ever reached the Studio compile.

THEOREM_GIT_TOKEN was printed in the build log

BuildKit prints every RUN instruction with its build args already substituted, so this

"https://x-access-token:${THEOREM_GIT_TOKEN}@github.com/..."

wrote the live PAT verbatim into Railway's persisted log store on every build. The stage carried the comment Never echo it. directly above the line that echoed it: a correct intention with a mechanism that defeats it.

Railway documents no secret mount for Dockerfile builds, so the fix keeps the value out of the instruction text:

  • Escape the $ so BuildKit prints the name and the shell expands the value from the arg's own environment at run time.
  • Use a git credential helper so the token never enters the URL, where it could resurface through git's progress output, a redirect notice, or the remote stored in .git/config. Same shape entrypoint.sh already uses.
  • GIT_TERMINAL_PROMPT=0 so a helper returning nothing fails fast instead of hanging on a prompt nobody can answer.

THEOREM_GIT_URL was declared, documented as the clone source, then ignored in favour of a hardcoded URL on the next line. Now used.

The token is already burned and needs rotating regardless of this fix, because it is in the logs of every build before this commit.

The Studio compile OOMed

FATAL ERROR: MarkCompactCollector: young object promotion failed
Allocation failed - JavaScript heap out of memory

exit 134, seven minutes in, at the mangle step. V8 refusing at its own configured ceiling is a different failure from the kernel reclaiming the process, and only the first is fixed by raising the limit. (The mac produced the second, which is why it is not the machine for this.)

Ceiling is now 12288MiB, overridable through STUDIO_NODE_HEAP_MB, because the right number is a property of the builder rather than of this repository. It should stay below the builder's memory: a ceiling above what the host can back turns this readable abort into a kernel kill that loses the stack.

Validation

  • shellcheck clean on build.sh (exit 0).
  • Zero unescaped ${THEOREM_GIT_TOKEN} occurrences remain in the Dockerfile.
  • The heap number is unverified. 12288 is a first estimate and the next build is the oracle: a 137 instead of a 134 means the builder cannot back it and the number comes down.

Two findings from deploy 39ea1ed3, the first build that reached the
Studio compile.

THEOREM_GIT_TOKEN was in the build log in plaintext. BuildKit prints
every RUN instruction with its build args already substituted, so the
clone URL carrying x-access-token:<pat> was written verbatim into
Railway's log store on every build. The stage carried the comment
"never echo it" directly above the line that echoed it, which is what a
correct intention with the wrong mechanism looks like. Escaping the $
defers expansion to the shell, so the printed instruction holds the
name; the credential helper then keeps the value out of the URL, where
it could otherwise resurface through git's progress output or the
stored remote. GIT_TERMINAL_PROMPT=0 turns a helper that returns
nothing into a failure rather than a build hung on a prompt.

THEOREM_GIT_URL was declared, documented as the clone source, and
ignored in favour of a hardcoded URL on the next line. It is now used.

The build then aborted at the mangle step with exit 134:

  FATAL ERROR: MarkCompactCollector: young object promotion failed
  Allocation failed - JavaScript heap out of memory

That is V8 refusing at its own ceiling, which is a different failure
from the kernel reclaiming the process, and only the first is fixed by
raising the limit. The mac produced the second and remains the wrong
machine for this. The ceiling is now 12288MiB, overridable through
STUDIO_NODE_HEAP_MB because the right number belongs to the builder and
not to this repository, and a ceiling above what the host can back
turns a readable abort into a kernel kill.

The token is already burned and wants rotating regardless: it is in the
logs of every build before this commit.
Copilot AI lite review requested due to automatic review settings August 4, 2026 14:43
@Travis-Gilbert
Travis-Gilbert merged commit e8c8ef5 into main Aug 4, 2026
2 of 3 checks passed
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Travis-Gilbert, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8d38e698-a53a-491f-8b52-46ba1a5903a6

📥 Commits

Reviewing files that changed from the base of the PR and between 2e24075 and 91ee83b.

📒 Files selected for processing (2)
  • packaging/commonplace-studio/scripts/build.sh
  • packaging/workspace/Dockerfile

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses two build/deploy problems: (1) preventing the THEOREM_GIT_TOKEN build arg from being exposed in Docker/BuildKit logs during the private Theorem clone, and (2) mitigating Node/V8 heap OOM during the CommonPlace Studio server (reh-web) compile by raising the Node heap ceiling with an override.

Changes:

  • Adjust Theorem clone in packaging/workspace/Dockerfile to avoid embedding the PAT in the clone URL and to rely on a git credential helper instead.
  • Add a configurable Node heap ceiling (STUDIO_NODE_HEAP_MB, default 12288) to reduce V8 heap OOMs during the Studio server build.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packaging/workspace/Dockerfile Reworks private Theorem clone authentication to avoid leaking THEOREM_GIT_TOKEN into build logs.
packaging/commonplace-studio/scripts/build.sh Raises Node heap ceiling for the Studio server gulp build and makes it overridable via env.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

&& apt-get install -y --no-install-recommends protobuf-compiler git ca-certificates \
&& rm -rf /var/lib/apt/lists/* \
&& if [ -z "${THEOREM_GIT_TOKEN}" ]; then \
&& if [ -z "\$THEOREM_GIT_TOKEN" ]; then \
Comment on lines +90 to +92
&& GIT_TERMINAL_PROMPT=0 git \
-c credential.helper='!f() { echo username=x-access-token; echo password=\$THEOREM_GIT_TOKEN; }; f' \
clone --depth 1 --branch "${THEOREM_GIT_REF}" "${THEOREM_GIT_URL}" /src \
Comment on lines +353 to +355
local heap_mb="${STUDIO_NODE_HEAP_MB:-12288}"
log "building the server: $target (node heap ceiling ${heap_mb}MiB)"
(

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 91ee83b71d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

&& git clone --depth 1 --branch "${THEOREM_GIT_REF}" \
"https://x-access-token:${THEOREM_GIT_TOKEN}@github.com/Travis-Gilbert/Theorem.git" /src \
&& GIT_TERMINAL_PROMPT=0 git \
-c credential.helper='!f() { echo username=x-access-token; echo password=\$THEOREM_GIT_TOKEN; }; f' \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Let the credential helper expand the token

When INCLUDE_EDITOR_SUBSTRATE=1 (the default), the single-quoted helper preserves this backslash, and Git later executes password=\$THEOREM_GIT_TOKEN; the helper shell therefore returns the literal string $THEOREM_GIT_TOKEN rather than the PAT. The private Theorem clone consequently receives invalid credentials and the workspace image cannot build. Remove the backslash here—the surrounding single quotes already prevent expansion by the outer RUN shell while allowing expansion when Git invokes the helper.

Useful? React with 👍 / 👎.

# than of this repository. Set it below the builder's memory: a ceiling
# above what the host can back converts this clean abort into a kernel kill,
# which is harder to read and loses the stack.
local heap_mb="${STUDIO_NODE_HEAP_MB:-12288}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Expose the heap override to the Docker build

When this target runs through the intended studio-server stage, Railway or docker build --build-arg STUDIO_NODE_HEAP_MB=... cannot override this value: packaging/workspace/Dockerfile declares only ARG BUILD_STUDIO_SERVER in that stage before invoking the script. Docker does not place an undeclared build argument in the RUN environment, so production image builds always select 12288. On a builder that cannot back a 12 GiB old-space ceiling—the exact situation the new comments say requires lowering it—the advertised escape hatch therefore cannot prevent a kernel OOM; declare the argument in the stage so the script receives it.

Useful? React with 👍 / 👎.

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.

2 participants