docs: the Coolify deploy hook is LIVE — six docs still call it a placeholder #33

Merged
admin merged 2 commits from docs/coolify-deploy-hook-is-live-opus5 into main 2026-09-06 08:05:08 +00:00
Owner

The finding

Six documents on main say some version of "no Coolify app has been provisioned for this repo;
cd.yml's COOLIFY_APP_ID is a literal placeholder that fails the job on purpose."

That is no longer true, and it is not a cosmetic staleness problem: a merge into main ships to
production today, while the repo's own README, ADR and runbook promise that it cannot.
I found
this the only way you can find it — by merging something and then reading the deploy job's log.

Evidence (measured, not assumed)

What How
Repo Actions secret COOLIFY_TOKEN exists, created 2026-08-31T11:34:34Z GET /api/v1/repos/sax3l/0pt/actions/secrets
Repo Actions variable COOLIFY_APP_ID exists with a real 24-character value — not the TODO-no-coolify-app-provisioned-yet literal GET /api/v1/repos/sax3l/0pt/actions/variables
Both guards in .gitea/workflows/cd.yml therefore pass, and the deploy actually fired push to main @ 1ff34410, run 11695, job 26295

From the job log:

::group::Run if [ -z "***" ]; then          <- COOLIFY_TOKEN is set, so -z is false
...
::group::Run curl -fsS -X POST \
  "https://cloud.siax.io/api/v1/deploy?uuid=${COOLIFY_APP_ID}&force=false" \
...
coolify deploy HTTP 200
🏁  Job succeeded

Deploy to Coolify / deploy (push) = success.

What this PR deliberately does NOT claim

That the Coolify app builds, starts, or serves anything, or that 0pt.app DNS points at it rather
than at Vercel. Nobody probed the running site. All that is proven is that the webhook is
accepted with HTTP 200. Every corrected passage says exactly that, so this does not swap one
unverified claim for another — which is why GOLDEN-STANDARD-REPORT.md D4 moves from ❌ to ⚠️ and
not to ✅.

Files corrected

  • README.md — "Deploy" section. Original bullet struck, not deleted; a new bullet states the
    measured state and the operational consequence ("know what you are shipping before you merge").
  • docs/02-architecture.md — the hosting SUPERSEDED callout.
  • docs/architecture/decisions/0001-deploy-target-coolify-not-vercel.md — the consequence is
    annotated with an UPDATE block; the decision text is untouched. An ADR is a historical record,
    so the original reads as "true when written 2026-08-09", not as current state.
  • docs/runbook/incident.md — the symptom row is now inverted. The old entry told an operator to
    expect a red deploy job; the real hazard today is the opposite, an unintended deploy.
  • docs/compliance/GOLDEN-STANDARD-REPORT.md — D4 ❌ → ⚠️.
  • docs/compliance/INVENTORY.md — the CI row's "deploy.yml röd men avsiktligt" claim.

Verification

Docs only — no workflow files, no .gitignore, no source. Falsifiable check over all six files
(a stale claim present without its correction marker is red):

origin/main                                  -> FAIL (12 findings)
this branch                                  -> PASS
mutation: drop only the README bullet        -> FAIL
mutation: drop only the runbook correction   -> FAIL

One honest note about the check itself: it first passed vacuously on docs/02-architecture.md,
because PR #32 had already placed the string CORRECTED 2026-09-06 in that file for an unrelated
reason. The marker was made specific so the check can actually fail there too — a gate that cannot
fall is worse than no gate.

node scripts/siax-doctor.mjs: 39/40, identical to main (the one failure, P1-15 CODEOWNERS, is
pre-existing and is what PR #19 supplies).

Generated with Claude Code

## The finding Six documents on `main` say some version of *"no Coolify app has been provisioned for this repo; `cd.yml`'s `COOLIFY_APP_ID` is a literal placeholder that fails the job on purpose."* That is no longer true, and it is not a cosmetic staleness problem: **a merge into `main` ships to production today, while the repo's own README, ADR and runbook promise that it cannot.** I found this the only way you can find it — by merging something and then reading the deploy job's log. ## Evidence (measured, not assumed) | What | How | |---|---| | Repo Actions **secret** `COOLIFY_TOKEN` exists, created `2026-08-31T11:34:34Z` | `GET /api/v1/repos/sax3l/0pt/actions/secrets` | | Repo Actions **variable** `COOLIFY_APP_ID` exists with a real 24-character value — **not** the `TODO-no-coolify-app-provisioned-yet` literal | `GET /api/v1/repos/sax3l/0pt/actions/variables` | | Both guards in `.gitea/workflows/cd.yml` therefore pass, and the deploy actually fired | push to `main` @ `1ff34410`, run **11695**, job **26295** | From the job log: ``` ::group::Run if [ -z "***" ]; then <- COOLIFY_TOKEN is set, so -z is false ... ::group::Run curl -fsS -X POST \ "https://cloud.siax.io/api/v1/deploy?uuid=${COOLIFY_APP_ID}&force=false" \ ... coolify deploy HTTP 200 🏁 Job succeeded ``` `Deploy to Coolify / deploy (push)` = **success**. ## What this PR deliberately does NOT claim That the Coolify app builds, starts, or serves anything, or that `0pt.app` DNS points at it rather than at Vercel. **Nobody probed the running site.** All that is proven is that the webhook is accepted with HTTP 200. Every corrected passage says exactly that, so this does not swap one unverified claim for another — which is why `GOLDEN-STANDARD-REPORT.md` D4 moves from ❌ to ⚠️ and not to ✅. ## Files corrected - `README.md` — "Deploy" section. Original bullet struck, not deleted; a new bullet states the measured state and the operational consequence ("know what you are shipping before you merge"). - `docs/02-architecture.md` — the hosting `SUPERSEDED` callout. - `docs/architecture/decisions/0001-deploy-target-coolify-not-vercel.md` — the *consequence* is annotated with an UPDATE block; the decision text is untouched. An ADR is a historical record, so the original reads as "true when written 2026-08-09", not as current state. - `docs/runbook/incident.md` — the symptom row is now inverted. The old entry told an operator to expect a red deploy job; the real hazard today is the opposite, an *unintended* deploy. - `docs/compliance/GOLDEN-STANDARD-REPORT.md` — D4 ❌ → ⚠️. - `docs/compliance/INVENTORY.md` — the CI row's "deploy.yml röd men avsiktligt" claim. ## Verification Docs only — no workflow files, no `.gitignore`, no source. Falsifiable check over all six files (a stale claim present without its correction marker is red): ``` origin/main -> FAIL (12 findings) this branch -> PASS mutation: drop only the README bullet -> FAIL mutation: drop only the runbook correction -> FAIL ``` One honest note about the check itself: it first passed **vacuously** on `docs/02-architecture.md`, because PR #32 had already placed the string `CORRECTED 2026-09-06` in that file for an unrelated reason. The marker was made specific so the check can actually fail there too — a gate that cannot fall is worse than no gate. `node scripts/siax-doctor.mjs`: 39/40, identical to `main` (the one failure, `P1-15 CODEOWNERS`, is pre-existing and is what PR #19 supplies). Generated with [Claude Code](https://claude.com/claude-code)
admin added 1 commit 2026-09-06 07:57:21 +00:00
docs: the Coolify deploy hook is LIVE — six docs still say it is a placeholder
CI (SIAX Cloud) / security (push) Successful in 31s
CI (SIAX Cloud) / integration (push) Successful in 42s
Security Scan (SIAX Cloud) / security (push) Successful in 44s
CI (SIAX Cloud) / quality (push) Successful in 1m6s
CI (SIAX Cloud) / security (pull_request) Successful in 30s
CI (SIAX Cloud) / integration (pull_request) Successful in 37s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 26s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m2s
d7a1c4d5e1
Six documents on main assert that no Coolify app has been provisioned for 0pt and
that cd.yml's COOLIFY_APP_ID is a literal placeholder whose guard fails the job on
purpose. That is no longer true, and the gap is not cosmetic: it means a merge to
main silently ships to production while the repo's own docs promise it cannot.

Measured, not assumed:

  * repo Actions secret  COOLIFY_TOKEN   exists, created 2026-08-31T11:34:34Z
    (GET /api/v1/repos/sax3l/0pt/actions/secrets)
  * repo Actions variable COOLIFY_APP_ID exists with a real 24-character value,
    not the "TODO-no-coolify-app-provisioned-yet" literal
    (GET /api/v1/repos/sax3l/0pt/actions/variables)
  * both guards in .gitea/workflows/cd.yml therefore pass; on the push to main at
    1ff34410 (2026-09-06) the job "Deploy to Coolify / deploy" (run 11695, job
    26295) finished SUCCESS with "coolify deploy HTTP 200" in its log

Deliberately NOT claimed: that the Coolify app builds, starts or serves, or that
0pt.app DNS points at it rather than Vercel. Nobody probed the running site, and
every corrected passage says so explicitly rather than replacing one unverified
claim with another.

Corrected: README.md "Deploy", docs/02-architecture.md hosting callout,
docs/architecture/decisions/0001 (consequence annotated, decision untouched --
an ADR is a historical record), docs/runbook/incident.md (the symptom row is now
inverted: the risk is an unintended deploy, not a red job),
docs/compliance/GOLDEN-STANDARD-REPORT.md D4 (❌ -> ⚠️, not ✅, because "webhook
accepted" is not "app serves"), docs/compliance/INVENTORY.md CI row.

Falsifiable check over all six files (stale claim present without a correction
marker = red):

  origin/main                                  -> FAIL (12 findings)
  this branch                                  -> PASS
  mutation: drop only the README bullet        -> FAIL
  mutation: drop only the runbook correction   -> FAIL

The check initially passed vacuously on docs/02-architecture.md because PR #32 had
already put the string "CORRECTED 2026-09-06" in that file for an unrelated reason;
the marker was made specific so the check could actually fail there too.

Docs only. No workflow files, no .gitignore, no source.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
admin added 1 commit 2026-09-06 08:01:21 +00:00
docs: probed 0pt.app — Vercel answers with HTTP 402 DEPLOYMENT_DISABLED
CI (SIAX Cloud) / security (push) Successful in 31s
CI (SIAX Cloud) / integration (push) Successful in 47s
CI (SIAX Cloud) / quality (push) Successful in 1m6s
Security Scan (SIAX Cloud) / security (push) Successful in 29s
CI (SIAX Cloud) / security (pull_request) Successful in 26s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 26s
CI (SIAX Cloud) / integration (pull_request) Successful in 41s
CI (SIAX Cloud) / quality (pull_request) Successful in 56s
853f09320c
The previous commit said "nobody has probed the running site". I then probed it,
so the docs should not keep hedging.

  curl -sI https://0pt.app/
    HTTP/2 402
    server: Vercel
    x-vercel-error: DEPLOYMENT_DISABLED
    strict-transport-security: max-age=63072000
  https://0pt.app/api/health -> HTTP 402, body "Payment required / DEPLOYMENT_DISABLED"

Two facts hold simultaneously and the docs now state both: the Coolify deploy hook
fires for real on every push to main, AND the public product domain is dark behind a
disabled Vercel deployment with DNS never cut over. Neither cancels the other.

Still not established, and still marked as such: whether the Coolify app builds and
starts. A deploy endpoint returning 200 means the request was accepted, not that a
container came up healthy.

Side note worth recording for PR #19: the HSTS header on that 402 response is
Vercel's platform default, which is exactly the disappearing-on-cutover risk
next.config.mjs in PR #19 was written to remove.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Author
Owner

Addendum — I then probed the running site, so the PR no longer hedges.

curl -sI https://0pt.app/
  HTTP/2 402
  server: Vercel
  x-vercel-error: DEPLOYMENT_DISABLED
  strict-transport-security: max-age=63072000

https://0pt.app/api/health -> HTTP 402, body: "Payment required / DEPLOYMENT_DISABLED"

Probed 2026-09-06 08:00 UTC. So two things are true at the same time, and the docs now say both:

  1. The Coolify deploy hook fires for real on every push to main (coolify deploy HTTP 200).
  2. The public product domain 0pt.app is dark — still pointed at Vercel, whose deployment is
    disabled for non-payment. DNS was never cut over, so the Coolify app serves no 0pt.app traffic.

Neither fact cancels the other, and the earlier "unverified" wording would have let a reader assume
whichever one suited them.

Still not established, and still labelled as such in the docs: whether the Coolify app builds and
starts at all. A deploy endpoint returning 200 means the request was accepted, not that a container
came up healthy.

One detail worth carrying to #19: the strict-transport-security header on that 402 is Vercel's
platform default
, not the app's. That is precisely the "HSTS silently disappears on cutover to
Coolify/Traefik" risk that next.config.mjs in #19 was written to remove — and it is unfixed on
main today.

Head is now 853f093; CI re-running.

Generated with Claude Code

**Addendum — I then probed the running site, so the PR no longer hedges.** ``` curl -sI https://0pt.app/ HTTP/2 402 server: Vercel x-vercel-error: DEPLOYMENT_DISABLED strict-transport-security: max-age=63072000 https://0pt.app/api/health -> HTTP 402, body: "Payment required / DEPLOYMENT_DISABLED" ``` Probed 2026-09-06 08:00 UTC. So two things are true at the same time, and the docs now say both: 1. The Coolify deploy hook **fires for real** on every push to `main` (`coolify deploy HTTP 200`). 2. The public product domain `0pt.app` is **dark** — still pointed at Vercel, whose deployment is disabled for non-payment. DNS was never cut over, so the Coolify app serves no `0pt.app` traffic. Neither fact cancels the other, and the earlier "unverified" wording would have let a reader assume whichever one suited them. Still not established, and still labelled as such in the docs: whether the Coolify app builds and starts at all. A deploy endpoint returning 200 means the request was accepted, not that a container came up healthy. One detail worth carrying to #19: the `strict-transport-security` header on that 402 is **Vercel's platform default**, not the app's. That is precisely the "HSTS silently disappears on cutover to Coolify/Traefik" risk that `next.config.mjs` in #19 was written to remove — and it is unfixed on `main` today. Head is now `853f093`; CI re-running. Generated with [Claude Code](https://claude.com/claude-code)
admin merged commit into main 2026-09-06 08:05:08 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/0pt#33