feat: add fast forge work-record reconciliation
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a053ff-1d6f-7fe2-ac1c-a6eb40a42a0c
This commit is contained in:
parent
a65cef02cf
commit
34f5cb3fc3
22 changed files with 799 additions and 162 deletions
80
Makefile
80
Makefile
|
|
@ -1,4 +1,4 @@
|
|||
.PHONY: install install-cli dashboard-install dashboard-check db db-tools migrate seed api dashboard check test test-python clean register-project register-codex-project register-mcp configure-codex bootstrap-env dev-hub edge-relay mcp-profile validate-adr add-domain rename-domain add-repo list-repos register-path register-from-classification register-from-classification-all cleanup-stale tunnels-up tunnels-status tunnels-check bridges install-hooks install-hooks-all gitea-inventory token-reconcile railiance-state-hub-render railiance-state-hub-client-dry-run railiance-state-hub-server-dry-run
|
||||
.PHONY: start install install-cli dashboard-install dashboard-check db db-tools migrate seed api dashboard dashboard-local sync check-primary primary-port-clear check check-local test test-python clean register-project register-codex-project register-mcp configure-codex bootstrap-env dev-hub edge-relay mcp-profile validate-adr add-domain rename-domain add-repo list-repos register-path register-from-classification register-from-classification-all cleanup-stale tunnels-up tunnels-status tunnels-check bridges install-hooks install-hooks-all gitea-inventory token-reconcile railiance-state-hub-render railiance-state-hub-client-dry-run railiance-state-hub-server-dry-run
|
||||
|
||||
COMPOSE = docker compose -f infra/docker-compose.yml --env-file .env
|
||||
PYTHON ?= python3
|
||||
|
|
@ -14,14 +14,23 @@ RAILIANCE_STATE_HUB_PLATFORM_DIR ?= deploy/railiance/platform
|
|||
RAILIANCE_STATE_HUB_APP_MANIFESTS ?= deploy/railiance/apps/manifests
|
||||
# Codex/WSL non-login shells may not source ~/.profile; keep uv discoverable.
|
||||
UV ?= $(shell command -v uv 2>/dev/null || if [ -x "$$HOME/.local/bin/uv" ]; then printf "%s" "$$HOME/.local/bin/uv"; else printf "%s" "uv"; fi)
|
||||
RMGR ?= $(shell command -v rmgr 2>/dev/null || if [ -x "$$HOME/repo-manager/.venv/bin/rmgr" ]; then printf "%s" "$$HOME/repo-manager/.venv/bin/rmgr"; else printf "%s" "rmgr"; fi)
|
||||
STATE_HUB_API_BASE ?= http://127.0.0.1:8000
|
||||
SYNC_PATH ?= .
|
||||
SYNC_PUSH ?= 1
|
||||
|
||||
start:
|
||||
@echo "# run in different terminals"
|
||||
@echo "make db # docker compose up postgres"
|
||||
@echo "make api # start backend api"
|
||||
@echo "make mcp-http # start state-hub mcp service"
|
||||
@echo "make dashboard # Observable dev server on :3000"
|
||||
@echo "make bridges # Set up ssh bridges for cross machines access"
|
||||
@echo "# Normal production UI access (run in order)"
|
||||
@echo "make bridges # connect local :8000 to the railiance01 primary"
|
||||
@echo "make dashboard # verify the primary, then serve the UI on :3000"
|
||||
@echo "make sync # push file-backed records and reconcile the exact forge commit"
|
||||
@echo ""
|
||||
@echo "# Optional local MCP adapter"
|
||||
@echo "make mcp-http # local SSE adapter on :8001; not needed by the UI"
|
||||
@echo ""
|
||||
@echo "# Local fallback/development only"
|
||||
@echo "make api # local Postgres + API; conflicts with the production :8000 tunnel"
|
||||
@echo "make dashboard-local # dashboard against the deliberate local API"
|
||||
|
||||
install:
|
||||
$(UV) sync
|
||||
|
|
@ -63,12 +72,56 @@ mcp-http:
|
|||
@fuser -k 8001/tcp 2>/dev/null && echo "Stopped running MCP server" || true
|
||||
MCP_TRANSPORT=sse MCP_PORT=8001 $(UV) run python mcp_server/server.py
|
||||
|
||||
dashboard:
|
||||
## Require the production identity before serving the normal dashboard. This
|
||||
## prevents an accidental local `make api` from presenting an empty fallback DB
|
||||
## as the live State Hub.
|
||||
check-primary:
|
||||
@health="$$(curl -fsS --max-time 5 http://127.0.0.1:8000/state/health 2>/dev/null)" || { \
|
||||
echo "ERROR: State Hub primary is not reachable on 127.0.0.1:8000." >&2; \
|
||||
echo "Run 'make bridges' first." >&2; \
|
||||
exit 1; \
|
||||
}; \
|
||||
identity="$$(printf '%s' "$$health" | $(PYTHON) -c 'import json, sys; d=json.load(sys.stdin); print("{}/{}".format(d.get("instance_role", ""), d.get("instance_label", "")))')"; \
|
||||
if [ "$$identity" != "primary/railiance01" ]; then \
|
||||
echo "ERROR: 127.0.0.1:8000 is '$$identity', not the primary/railiance01 State Hub." >&2; \
|
||||
echo "Stop the local API, then run 'make bridges'. Use 'make dashboard-local' only for intentional local development." >&2; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
## Refuse to start the production tunnel when a non-primary API already owns
|
||||
## port 8000. With no listener, bridge is free to establish the tunnel.
|
||||
primary-port-clear:
|
||||
@if health="$$(curl -fsS --max-time 2 http://127.0.0.1:8000/state/health 2>/dev/null)"; then \
|
||||
identity="$$(printf '%s' "$$health" | $(PYTHON) -c 'import json, sys; d=json.load(sys.stdin); print("{}/{}".format(d.get("instance_role", ""), d.get("instance_label", "")))')"; \
|
||||
if [ "$$identity" != "primary/railiance01" ]; then \
|
||||
echo "ERROR: port 8000 is occupied by '$$identity'." >&2; \
|
||||
echo "Stop the local 'make api' process before starting the production tunnel." >&2; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
fi
|
||||
|
||||
dashboard: check-primary
|
||||
@fuser -k 3000/tcp 2>/dev/null && echo "Stopped running dashboard" || true
|
||||
$(MAKE) dashboard-install
|
||||
cd dashboard && npm run dev
|
||||
|
||||
check:
|
||||
## Deliberate local-development dashboard; bypasses the production identity gate.
|
||||
dashboard-local:
|
||||
@echo "WARNING: serving the dashboard against the local/fallback API on :8000."
|
||||
@fuser -k 3000/tcp 2>/dev/null && echo "Stopped running dashboard" || true
|
||||
$(MAKE) dashboard-install
|
||||
cd dashboard && npm run dev
|
||||
|
||||
## Fast work-record path. Repo Manager assigns only missing deterministic IDs,
|
||||
## verifies the primary/railliance01 bridge, and asks central to derive the
|
||||
## exact pushed Forgejo commit in one transactional request.
|
||||
sync:
|
||||
$(RMGR) sync --path "$(SYNC_PATH)" --api-base "$(STATE_HUB_API_BASE)" $(if $(filter 1 true yes,$(SYNC_PUSH)),--push,)
|
||||
|
||||
check: check-primary
|
||||
@echo "State Hub primary/railiance01 is healthy."
|
||||
|
||||
check-local:
|
||||
curl -sf http://127.0.0.1:8000/state/health | python3 -m json.tool
|
||||
|
||||
# CUST-WP-0067-T09. The chart ships a copy of the-custodian canon allowed-values
|
||||
|
|
@ -136,7 +189,7 @@ benchmark-summary-cache:
|
|||
|
||||
## ops-bridge managed tunnels
|
||||
## Requires ops-bridge: bridge is at /home/worsch/.local/bin/bridge
|
||||
tunnels-up:
|
||||
tunnels-up: primary-port-clear
|
||||
bridge up
|
||||
|
||||
tunnels-status:
|
||||
|
|
@ -149,7 +202,7 @@ tunnels-check:
|
|||
|
||||
## Ensure all ops-bridge tunnels are up and healthy.
|
||||
## Brings up any stopped/stale tunnels, shows final status, exits non-zero if anything is still down.
|
||||
bridges:
|
||||
bridges: primary-port-clear
|
||||
@echo "==> Bringing up all tunnels..."
|
||||
bridge up
|
||||
@echo ""
|
||||
|
|
@ -159,9 +212,10 @@ bridges:
|
|||
@echo "==> Checking tunnel health..."
|
||||
bridge check
|
||||
|
||||
## Start (or restart) the full backend — db + migrate + uvicorn.
|
||||
## Stops uvicorn on :8000 if already running, then starts fresh.
|
||||
## Start (or restart) the LOCAL FALLBACK backend — db + migrate + uvicorn.
|
||||
## This replaces anything on :8000, including the production State Hub tunnel.
|
||||
api: db
|
||||
@echo "WARNING: starting the local fallback API; this is not the railiance01 primary."
|
||||
@echo "Waiting for postgres..."; \
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do \
|
||||
nc -z 127.0.0.1 5432 2>/dev/null && break; \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue