Commit Graph
46 Commits
Author SHA1 Message Date
gtiandClaude Opus 5.5 91a2dda969 feat: publish the Hub through a reverse proxy on another host
GTI terminates TLS in its Nginx Proxy Manager (10.0.10.100), not on the
Hub host, so the Hub must be reachable on the LAN — by the proxy only.

- docker-compose.prod.yml passes FORWARDED_ALLOW_IPS (uvicorn then trusts
  X-Forwarded-For/-Proto from the proxy only: real client IPs in audit and
  session records, https scheme) and WEB_COOKIE_SECURE. Defaults keep the
  previous behaviour.
- restrict_hub_port.sh + gti-fiscal-hub-port.service: Docker-published
  ports bypass UFW, so the source restriction lives in DOCKER-USER,
  matched on the conntrack original destination with --ctdir ORIGINAL,
  and is re-applied whenever docker.service starts (the chain is not
  persisted across reboots).
- *.service forced to LF like *.sh; tests cover both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 07:46:11 -03:00
gtiandClaude Opus 5.5 d33149f5ee docs: record migration head 0020 in the release manifest and docs
RELEASE_MANIFEST.json still said head 0011 (repo was at 0018, now 0020)
and RELEASE_CANDIDATE_V1.md said 0010. Updated both, plus
AI_PROJECT_STATE.md and PILOT_DEPLOYMENT.md, to head
0020_not_null_timestamps as applied in production.

scripts/release_manifest.py reported the 4-digit file prefix as the head
("0020" instead of "0020_not_null_timestamps") and always read the
applied revision from the dev container. It now asks Alembic for the real
head and revision count, and the Hub container is configurable
(HUB_CONTAINER); the source is recorded in the manifest.

tests/test_release_candidate.py now fails when the manifest head differs
from Alembic's head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 07:23:13 -03:00
gtiandClaude Opus 5.5 6bcfac6497 fix: enforce NOT NULL on 20 server-defaulted timestamp columns
Audit of models vs fresh DB vs production (all at 0019): 20 columns are
NOT NULL in the models but nullable in the database, all timestamps with
DEFAULT now() created by 0011/0012/0014/0017 without nullable=False.

Classified DB_CONSTRAINT_MISSING: no application path writes NULL to
them (inserts omit them, updates set now; no raw SQL inserts), and there
were zero NULLs in production and in the development database (246,682
rows checked). The upgrade aborts without changing anything if any NULL
is present, instead of inventing a value.

After this revision a fresh database matches the models on nullability,
column types, PKs, FKs, uniqueness and checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 07:20:04 -03:00
gtiandClaude Opus 5.5 b6b45c703b fix: make the Hub backup scripts runnable on the Linux host
Found by running deploy/hub/backup.sh on the production VM:

- With core.autocrlf=true, `git archive` on the Windows release machine
  shipped the .sh files with CRLF and `sh` aborted on line 4
  ("set: Illegal option -"): backup, restore and seed never ran.
  .gitattributes now forces *.sh to LF.
- Docker creates the bind-mounted backups/ directory as root, so the
  host-side retention `rm` would fail once the 15th dump existed.
  Retention now runs inside the postgres container.

tests/test_deploy_scripts.py covers both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 00:35:20 -03:00
gtiandClaude Opus 5.5 a11209d123 fix: make the migration chain runnable from an empty database
0001 called Base.metadata.create_all(), building the schema from the
current models, so on a fresh PostgreSQL 0002 collided on
datasets.raw_sha256 and `alembic upgrade head` could never run from zero.

0001 is now an explicit, frozen baseline: the seven base tables exactly as
the real history created them, before 0002/0006 extended them. Databases
already past 0001 never re-run it. Proof: a fresh `upgrade head` produces a
schema identical (pg_dump --schema-only) to the long-lived dev database.

0019 repairs a latent bug found by that comparison: 0006 used
server_default="now()" as a string, which PostgreSQL froze at the instant
the column was created, so every Agent and Job got the same created_at.
It also adds three indexes the models declare but no migration created.

central/tests/test_migration_baseline.py guards (via AST) against
migrations importing the models or using string timestamp defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 00:30:51 -03:00
gti ce606b04cc fix: reconcile final control panel coverage UX 2026-09-22 23:04:53 -03:00
gti 283749e860 docs: clarify legacy blocker resolution limits 2026-09-22 21:46:44 -03:00
gti 50254772e4 fix: clarify unavailable legacy blocker resolution 2026-09-22 21:42:24 -03:00
gti c23782095c fix: keep migration and blocker SQL postgres-safe 2026-09-22 21:29:09 -03:00
gti c2507aee35 fix: show technical timestamps in tooltips 2026-09-22 21:05:39 -03:00
gti f05e4a10a2 docs: record control panel UX task 5 report 2026-09-22 20:50:04 -03:00
gti 4ba0fa8a53 test: complete control panel fixture UX coverage 2026-09-22 20:49:04 -03:00
gti 0eeb7d159c fix: close operational panel page review findings 2026-09-22 20:34:03 -03:00
gti a4d837f151 feat: refine operational control panel pages 2026-09-22 20:11:18 -03:00
gti 06f6d0f940 fix: enforce utf8 resolution limits 2026-09-22 19:20:45 -03:00
gti 516c71b932 fix: close task 3 resolution findings 2026-09-22 19:11:08 -03:00
gti 5180725238 feat: add safe blocker resolution workflow 2026-09-22 18:47:04 -03:00
gti 25af5cf0f0 docs: append task 2 re-review report 2026-09-22 18:24:08 -03:00
gti 2ee271ca80 fix: close remaining task 2 review findings 2026-09-22 18:23:38 -03:00
gti 041257d254 docs: append task 2 review fix report 2026-09-22 18:01:04 -03:00
gti e35417f044 fix: close task 2 operational review findings 2026-09-22 18:00:28 -03:00
gti 34744ac75a docs: record operational view model task 2 2026-09-22 17:37:46 -03:00
gti d72971047b feat: add bounded operational view models 2026-09-22 17:34:47 -03:00
gti 5fd04f9de4 docs: append weak password fix report 2026-09-22 17:16:54 -03:00
gti de571e3ac2 fix: fail closed weak password opt-in 2026-09-22 17:16:02 -03:00
gti ab3aaaae8a docs: record operational panel task 1 report 2026-09-22 17:00:20 -03:00
gti 0846b9d1b0 feat: add operational panel presentation helpers 2026-09-22 16:59:05 -03:00
gti 9f1c259c3e docs: plan operational control panel ux 2026-09-22 16:45:35 -03:00
gti 8bbfaf6ac6 docs: specify operational control panel ux 2026-09-22 16:43:20 -03:00
gti 35642959c0 fix: allow local development admin password 2026-09-22 16:31:33 -03:00
gti 6bdac245b9 fix: validate control panel runtime paths 2026-09-22 16:23:51 -03:00
gti 66b5888d80 feat: add blocker resolution action to panel 2026-09-22 15:38:55 -03:00
gti 301aac112e feat: add autonomous fiscal control panel 2026-09-22 15:36:12 -03:00
gti 636ed5228b docs: add control panel v1 implementation plan 2026-09-22 15:08:26 -03:00
gti 304a916890 docs: specify control panel v1 architecture 2026-09-22 15:05:12 -03:00
gti 3a36ac630b feat: close autonomous operations for blocked products 2026-09-22 14:51:54 -03:00
gti dca4847c21 feat: close final incomplete product analysis 2026-09-22 14:34:15 -03:00
gti e3ac68c70e feat: add autonomous fiscal completion v1 2026-09-22 13:08:38 -03:00
gti eada0df37e docs: plan autonomous fiscal completion v1 2026-09-22 12:40:48 -03:00
gti b3e8dd1b24 docs: design autonomous fiscal completion v1 2026-09-22 12:37:38 -03:00
gti df3c44838a docs: record final pre-zai local closure 2026-09-22 12:17:05 -03:00
OpenCode a6492f936e docs: record pre-zai closure design 2026-09-21 16:50:45 -03:00
OpenCode b10131953c feat: close pre-zai local blockers 2026-09-21 16:46:59 -03:00
OpenCode 84b08c2150 feat: complete pre-ai local completion v3 2026-09-21 16:30:27 -03:00
OpenCode 6731eeca08 chore: capture semantic pipeline baseline 2026-09-21 15:52:17 -03:00
OpenCode 9dcc263217 chore: establish project baseline 2026-09-21 15:51:47 -03:00