Commit graph

14 commits

Author SHA1 Message Date
Daniel
993442f98a feat: the API describes itself, at /api/openapi.json
docs/api-reference.md was hand-written, and by the time anyone checked
it was documenting twenty-three endpoints that answer 404 while missing
others that exist. That is what hand-written reference material does: it
is correct on the day it is written and silently wrong afterwards. A
second hand-written document, in YAML this time, would rot the same way.

So paths, methods and mount points are read from the Express router
stack at request time. They cannot disagree with the app, because they
are the app: 186 paths, 215 operations, and — checked — no /learning
endpoints, which is what the prose version went on claiming for weeks
after that feature was deleted.

What introspection cannot know is what an endpoint is *for*. That half
lives in src/utils/openapiRoutes.js, keyed by "METHOD /path", and it is
the half that rots, so it is the half that is enforced: a Playwright
spec fetches the live document and fails when the number of operations
without a summary rises above 199 — the debt as measured today. A
ratchet, not a target. Adding an endpoint pushes the count over and
fails the build; describing one lowers the number. The failure lists the
operations by name, so it says what to write.

Whether an operation is public is stated per route rather than inferred
from middleware. Guessing wrong there is worse in both directions:
calling a public endpoint protected hides a hole, and the reverse
invites a bug report.

The contract spec lives in e2e rather than the unit suite because it
needs the whole app mounted, and requiring server.js from node:test
pulls in the database pool and hangs the run — that has happened here
before.

Also: e2e now runs in CI on dev, gated by a shell check inside the step
rather than a job-level "if", which this Forgejo dispatches anyway and
then kills with "Early termination".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-13 00:52:55 +02:00
Daniel
36cb742ce7 ci: fix the failing job, split deploy out, and drop the Android build
All checks were successful
Forgejo Docker Build / Root app tests (push) Successful in 54s
Forgejo Docker Build / Build Docker image (push) Successful in 7s
Three things, one subject: making CI say the truth about this repo.

## The red on every run was ours, not the runners'

Every docker-build run came back success, success, failure — the same
shape for weeks. The failing job was `deploy`, and it was failing to
*not run*:

    if: ${{ github.event.inputs.deploy == 'true' }}

On a push there is no github.event.inputs at all. This Forgejo does not
treat that as false and skip; it dispatches the job, the runner cannot
resolve it, and the task ends in "Early termination". The runners were
never at fault, and nothing about them needed changing.

The `'runs-on' key not defined` line is a red herring: the `build` job
prints it too and succeeds. It names the job's *needs* target, not the
job, and the old android-apk workflow used `needs:` happily for months.

Deploy is now its own workflow with only workflow_dispatch — no
condition to evaluate, so nothing can be dispatched by mistake. No job
in either file now carries a job-level `if`. The one conditional left is
a *step* (push to registry), and step conditions are evaluated by the
runner once the job is already running, which is why that one has always
worked.

## dev and main

docker-build now runs on `dev` as well. Both branches prove the same two
things — tests pass, image builds — and only `main` publishes the image,
so nothing on `dev` can be mistaken for something deployable. Deploying
stays a person pressing a button after looking at the change.
CONTRIBUTING.md documents the flow.

## Android

Removed: the mobile/ Capacitor project, docs/mobile-build.md, and the
Android bits of scripts/release.sh. All of it is in git history — 4613a278
is the last commit that had it — for when it is rebuilt.

src/utils/platform.js stays. isMobileClient only decides token lifetime,
it is twelve lines, and it is the contract a future app would come back
to; deleting it would be a change to auth for no gain.

.github/workflows/ went too — all five. There is no GitHub remote on
this repository, so none of them has ever run, and two of them wrote
into mobile/ paths that no longer exist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-12 23:30:52 +02:00
Daniel
8ae47feeff build: drop the Android APK workflows; CI is the Docker image and the web app
Requested: no more Android building, focus on the Docker app build and
the web app.

android-apk.yml also ran on every push to every branch, so every commit
started an APK build beside the one workflow anyone was watching. Worse,
its runner — ped-ai-android-runner — advertises the same forgejo-local
label as the general runner, so it was also picking up the Docker build
job and dying instantly with "'runs-on' key not defined". That is why
docker-build showed a failure next to a success on the same commit.

Removed: .forgejo/workflows/android-apk.yml, and the two GitHub APK
workflows, which never ran at all — there is no GitHub remote on this
repo, only forgejo.

The Capacitor project under mobile/ is untouched and still builds by
hand; docs/mobile-build.md now says plainly that nothing builds it for
you.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-12 22:24:17 +02:00
Daniel
8d0dc968b3 feat: a deploy you can repeat, and prove afterwards
Reproducibility means two things here: the same commit builds the same image,
and the running container can be asked which commit it is.

  - Base images are pinned by digest, not by tag. A tag moves; two builds of one
    commit could otherwise differ. These are manifest-list digests, so buildx
    still picks the right architecture.

  - scripts/build-image.sh also writes ped-ai-local:<revision>, an immutable
    name a deploy can refer to instead of chasing :latest. Its summary goes to
    stderr so stdout stays the Compose invocation.

  - Compose takes the image from PED_AI_IMAGE, so a deploy runs a specific
    revision-tagged image while a local build still uses the local tag.

  - scripts/deploy.sh pins that image in the file Compose interpolates from,
    waits for health, then asks /api/build which revision is actually serving
    and rolls back to the previous image if it does not match. Healthy is not
    the same as running what you asked for. The rollback path was exercised.

  - The entrypoint applies migrations before the app starts, so code and schema
    arrive together. node-pg-migrate takes an advisory lock; losing it is not an
    error, it waits and looks again, so a rolling restart does not fail. A real
    migration failure stops the container rather than serving on a schema that
    does not match the build. RUN_MIGRATIONS=false opts out.

  - The Forgejo workflow builds through that same script, tags by full revision,
    and has an opt-in deploy job. It refuses to run if the deploy directory has
    uncommitted work rather than resetting over it.

The running image was labelled revision=unknown, and /api/build said "unknown",
because `docker compose up --build` never passes GIT_REVISION. That is exactly
the hole this closes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-11 00:41:11 +02:00
Daniel
cfaf8e957b feat: ship reviewed prompt history, conversation limits and account protections 2026-09-07 04:01:01 +02:00
Daniel
e1266c6d38 ci: route Android APK through Forgejo releases
Some checks failed
Forgejo Android APK / Build signed APK (push) Has been cancelled
2026-05-11 04:21:15 +02:00
Daniel
f871384063 fix mobile assistant export and image actions
Some checks failed
Forgejo Android APK / Build signed APK (push) Has been cancelled
2026-05-10 20:28:46 +02:00
Daniel
977ebfc037 ci: publish forgejo apk releases 2026-05-10 19:37:52 +02:00
Daniel
212ce7dd95 ci: use forgejo-compatible artifact upload 2026-05-10 18:48:40 +02:00
Daniel
b29c6f7717 ci: harden forgejo android signing restore 2026-05-10 18:31:57 +02:00
Daniel
8f51e56723 ci: fetch android setup actions from github 2026-05-10 18:24:12 +02:00
Daniel
7fe0a0e7ec ci: prepare compose env files in forgejo 2026-05-10 18:21:18 +02:00
Daniel
71655aa7e9 ci: use forgejo local runner label 2026-05-10 18:13:14 +02:00
Daniel
52544e9116 ci: add forgejo build workflows 2026-05-10 18:05:55 +02:00