<feed xmlns='http://www.w3.org/2005/Atom'>
<title>progmaweb, branch content/catalog-without-tala</title>
<subtitle>The site and account service of Progmasoft: a Next.js frontend and an ASP.NET Core API.</subtitle>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/'/>
<entry>
<title>Merge branch 'main' into content/catalog-without-tala</title>
<updated>2026-11-13T02:06:08+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-13T02:06:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=d82258f9f3bb23a0f59d79b984ff527942efc0f0'/>
<id>d82258f9f3bb23a0f59d79b984ff527942efc0f0</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #65 from Progmasoft/ops/git-mirrors</title>
<updated>2026-11-13T02:06:03+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-13T02:06:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=f980fee24c5302173fa00ab758b7c54213d2bb7a'/>
<id>f980fee24c5302173fa00ab758b7c54213d2bb7a</id>
<content type='text'>
Add read-only Git mirrors on git.progmasoft.com</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add read-only Git mirrors on git.progmasoft.com</pre>
</div>
</content>
</entry>
<entry>
<title>Format the catalog and the site tests with Prettier</title>
<updated>2026-11-12T23:00:34+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T23:00:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=189b15ca0909033a40626bc8f600686e561b9cbb'/>
<id>189b15ca0909033a40626bc8f600686e561b9cbb</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Take the Tala products out of the catalog and describe the new Tazel</title>
<updated>2026-11-12T23:00:18+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T23:00:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=9a6cfb275189db7cb8d4a35917678d067b3e709a'/>
<id>9a6cfb275189db7cb8d4a35917678d067b3e709a</id>
<content type='text'>
Tala and its tools are no longer developed (2026-11-10), and tala.run,
talac.tala.run, talafmt.tala.run and talalint.tala.run lead to a notice
that answers 503. The catalog still offered Tala, talac, talafmt and
talalint with "Visit the site" buttons into that notice, and described
Tazel as the build system of Tala.

- Tala, talac, talafmt and talalint leave the catalog in all four
  languages, as Xide did; their product pages answer 404.
- The catalog names Tazel and Catch3.
- Tazel is described as it is now: it builds C, C++, Objective-C,
  Objective-C++ and Zig from MODULE.kts and BUILD.kts, finds Clang, GCC
  and zig cc, builds for other triples, is incremental per action, and
  runs commands of tazel_custom.txt. Nothing it does not do yet (ViGet
  packages, plugins) is promised.
- The site tests list the two products and route through them.

Answers the review of website#58, which found the product links leading
into the closed sites.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Tala and its tools are no longer developed (2026-11-10), and tala.run,
talac.tala.run, talafmt.tala.run and talalint.tala.run lead to a notice
that answers 503. The catalog still offered Tala, talac, talafmt and
talalint with "Visit the site" buttons into that notice, and described
Tazel as the build system of Tala.

- Tala, talac, talafmt and talalint leave the catalog in all four
  languages, as Xide did; their product pages answer 404.
- The catalog names Tazel and Catch3.
- Tazel is described as it is now: it builds C, C++, Objective-C,
  Objective-C++ and Zig from MODULE.kts and BUILD.kts, finds Clang, GCC
  and zig cc, builds for other triples, is incremental per action, and
  runs commands of tazel_custom.txt. Nothing it does not do yet (ViGet
  packages, plugins) is promised.
- The site tests list the two products and route through them.

Answers the review of website#58, which found the product links leading
into the closed sites.
</pre>
</div>
</content>
</entry>
<entry>
<title>Serve only listed mirrors and report a failed default-branch lookup</title>
<updated>2026-11-12T22:57:15+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T22:57:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=05d42b1a4ca923ee7726c35c261bfc75d32ddea3'/>
<id>05d42b1a4ca923ee7726c35c261bfc75d32ddea3</id>
<content type='text'>
- git-http-backend no longer exports every directory under the mirror
  root: GIT_HTTP_EXPORT_ALL is gone, git-mirror marks each listed mirror
  with git-daemon-export-ok, and a mirror taken off the list loses the
  mark and is deleted on the next run. Tried live: an unlisted bare
  repository answered 404 and was removed by the next run.
- git-mirror checks git ls-remote before it reads the default branch
  and fails the run when the lookup fails.
- The README explains the /usr/bin spelling of the fcgiwrap label (an
  equivalence of /usr/sbin), the stock label of /srv/*/www, and where
  the DNS record is kept.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- git-http-backend no longer exports every directory under the mirror
  root: GIT_HTTP_EXPORT_ALL is gone, git-mirror marks each listed mirror
  with git-daemon-export-ok, and a mirror taken off the list loses the
  mark and is deleted on the next run. Tried live: an unlisted bare
  repository answered 404 and was removed by the next run.
- git-mirror checks git ls-remote before it reads the default branch
  and fails the run when the lookup fails.
- The README explains the /usr/bin spelling of the fcgiwrap label (an
  equivalence of /usr/sbin), the stock label of /srv/*/www, and where
  the DNS record is kept.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add read-only Git mirrors on git.progmasoft.com</title>
<updated>2026-11-12T20:41:27+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T20:41:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=83e0ad4586d90bf02c3a5bfeb1ab92fd90e51703'/>
<id>83e0ad4586d90bf02c3a5bfeb1ab92fd90e51703</id>
<content type='text'>
git.progmasoft.com shows the public repositories under development
(tazel, tazelish, tazel.net, catch3, progmasoft-cpp, progmaweb, website)
as read-only mirrors with cgit, and serves clones over smart HTTP, such
as git clone https://git.progmasoft.com/tazel. GitHub stays where
development happens; private and archived repositories are not mirrored.

ops/git holds what runs on the server:

- cgitrc, the header, footer and stylesheet: the look of progmasoft.com
  (its tokens, the four-tile brand with "Git" beside it, the dark
  footer), light like its default, no scripts, no rendered READMEs.
- git-mirror.sh with git-mirror.service/.timer: every ten minutes, as
  gitmirror, branches and tags only from GitHub, pruned, the default
  branch followed, repacked with a bitmap when something changed.
- fcgiwrap@cgit drop-ins: cgit and git-http-backend run as cgit with
  systemd sandboxing (no network, read-only system, exposure 0.7), on
  a socket only nginx can open.
- selinux/progmasoft_cgit.te: fcgiwrap runs in httpd_t and the two
  CGIs move into git_script_t; the module allows only that move under
  the NoNewPrivileges that the sandboxing sets.
- nginx/git.conf: HSTS, a content security policy without scripts,
  per-address request and connection limits, 403 for receive-pack and
  the dumb protocol, buffered clones, and the inline handlers of cgit's
  menus removed.

ops/README.md describes the files, the labels, and why the name is not
behind the Cloudflare proxy: through it a clone of catch3 never reached
the client.

Deployed and checked live: every page answers 200, unknown ones 404,
full clones of tazel, progmaweb and catch3 work, a push answers 403,
no SELinux denials, no console errors, no horizontal scroll at 390 px.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
git.progmasoft.com shows the public repositories under development
(tazel, tazelish, tazel.net, catch3, progmasoft-cpp, progmaweb, website)
as read-only mirrors with cgit, and serves clones over smart HTTP, such
as git clone https://git.progmasoft.com/tazel. GitHub stays where
development happens; private and archived repositories are not mirrored.

ops/git holds what runs on the server:

- cgitrc, the header, footer and stylesheet: the look of progmasoft.com
  (its tokens, the four-tile brand with "Git" beside it, the dark
  footer), light like its default, no scripts, no rendered READMEs.
- git-mirror.sh with git-mirror.service/.timer: every ten minutes, as
  gitmirror, branches and tags only from GitHub, pruned, the default
  branch followed, repacked with a bitmap when something changed.
- fcgiwrap@cgit drop-ins: cgit and git-http-backend run as cgit with
  systemd sandboxing (no network, read-only system, exposure 0.7), on
  a socket only nginx can open.
- selinux/progmasoft_cgit.te: fcgiwrap runs in httpd_t and the two
  CGIs move into git_script_t; the module allows only that move under
  the NoNewPrivileges that the sandboxing sets.
- nginx/git.conf: HSTS, a content security policy without scripts,
  per-address request and connection limits, 403 for receive-pack and
  the dumb protocol, buffered clones, and the inline handlers of cgit's
  menus removed.

ops/README.md describes the files, the labels, and why the name is not
behind the Cloudflare proxy: through it a clone of catch3 never reached
the client.

Deployed and checked live: every page answers 200, unknown ones 404,
full clones of tazel, progmaweb and catch3 work, a push answers 403,
no SELinux denials, no console errors, no horizontal scroll at 390 px.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #61 from Progmasoft/security/cloudflare-real-ip</title>
<updated>2026-11-09T21:44:57+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-09T21:44:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=80d46cbffc87da9bf2665935e563ab556c1a267d'/>
<id>80d46cbffc87da9bf2665935e563ab556c1a267d</id>
<content type='text'>
Rate-limit sign-in by visitor behind Cloudflare and stop forwarding h2c</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rate-limit sign-in by visitor behind Cloudflare and stop forwarding h2c</pre>
</div>
</content>
</entry>
<entry>
<title>Merge remote-tracking branch 'origin/main' into security/cloudflare-real-ip</title>
<updated>2026-11-08T22:18:34+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-08T22:18:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=c0bafe9050161ea6ca0c49f54897f908ca16ce84'/>
<id>c0bafe9050161ea6ca0c49f54897f908ca16ce84</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #60 from Progmasoft/feature/remove-xide</title>
<updated>2026-11-08T22:17:43+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-08T22:17:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=3ac256e69f10a3bb78d394c77d03a88a72261597'/>
<id>3ac256e69f10a3bb78d394c77d03a88a72261597</id>
<content type='text'>
Remove Xide and ides.progmasoft.com</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Remove Xide and ides.progmasoft.com</pre>
</div>
</content>
</entry>
<entry>
<title>Rate-limit sign-in by visitor behind Cloudflare and stop forwarding h2c</title>
<updated>2026-11-08T21:38:47+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-08T21:38:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=66f3cc196a9b91d471a90e021b12630100181c4a'/>
<id>66f3cc196a9b91d471a90e021b12630100181c4a</id>
<content type='text'>
Cloudflare proxies the Progmasoft hosts, so Nginx saw a Cloudflare edge as
its peer and appended that edge to X-Forwarded-For. The API takes the last
hop as the client, so the account-auth limit (12 attempts in 3 minutes) was
counted per edge: 38 failed sign-ins from one address in a row were all
answered with 401, none with 429, and unrelated visitors behind one edge
shared a bucket.

- ops/nginx/cloudflare-real-ip.conf trusts CF-Connecting-IP only from the
  published Cloudflare ranges; a direct peer keeps its own address, so the
  header cannot be forged around Cloudflare. With it installed the 13th
  failed sign-in gets 429, a forged X-Forwarded-For changes nothing, and
  another address is not affected.
- Every proxied location forwarded the client's Upgrade header with
  "Connection: upgrade" on each request. Only a WebSocket upgrade is now
  forwarded; other requests carry no Upgrade and an empty Connection.
- c8 reached glob 13 (GHSA-3g3m-2fjr-6pw4) and minimatch 10
  (GHSA-g3hv-75wg-m249) through test-exclude; both are overridden to the
  fixed majors. pnpm audit reports nothing, coverage, lint and check pass.
- The CodeQL action pins carry their exact version comment (v4.38.2).
- ops/README.md describes the address handling and no longer names a
  script that left the repository with AI Support.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Cloudflare proxies the Progmasoft hosts, so Nginx saw a Cloudflare edge as
its peer and appended that edge to X-Forwarded-For. The API takes the last
hop as the client, so the account-auth limit (12 attempts in 3 minutes) was
counted per edge: 38 failed sign-ins from one address in a row were all
answered with 401, none with 429, and unrelated visitors behind one edge
shared a bucket.

- ops/nginx/cloudflare-real-ip.conf trusts CF-Connecting-IP only from the
  published Cloudflare ranges; a direct peer keeps its own address, so the
  header cannot be forged around Cloudflare. With it installed the 13th
  failed sign-in gets 429, a forged X-Forwarded-For changes nothing, and
  another address is not affected.
- Every proxied location forwarded the client's Upgrade header with
  "Connection: upgrade" on each request. Only a WebSocket upgrade is now
  forwarded; other requests carry no Upgrade and an empty Connection.
- c8 reached glob 13 (GHSA-3g3m-2fjr-6pw4) and minimatch 10
  (GHSA-g3hv-75wg-m249) through test-exclude; both are overridden to the
  fixed majors. pnpm audit reports nothing, coverage, lint and check pass.
- The CodeQL action pins carry their exact version comment (v4.38.2).
- ops/README.md describes the address handling and no longer names a
  script that left the repository with AI Support.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
