Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
a864ae3
feat(data): implement MarkdownGenerator age_days trigger via heuristi…
w7-mgfcode May 14, 2026
1b4447d
feat(api,docs): e2e demo pipeline + showcase script (#128) (#129)
w7-mgfcode May 14, 2026
7034e48
chore(repo): bump authlib + fastmcp to clear Socket-flagged CVEs (#13…
w7-mgfcode May 14, 2026
51d9149
feat(api,ui): in-product demo showcase page (#132) (#133)
w7-mgfcode May 17, 2026
ec212de
chore(repo): back-merge main into dev to absorb v0.2.10 release commi…
w7-mgfcode May 18, 2026
7774ef1
docs(docs): fix broken PRP-0/INITIAL-0 relative links in phase 0 doc …
w7-mgfcode May 18, 2026
3358b04
docs(repo): fix readme dev-deps command and stale .github template pl…
w7-mgfcode May 18, 2026
087bc58
docs(docs): fill DEV_GUIDE.md onboarding stub sections (#142) (#143)
w7-mgfcode May 18, 2026
d505788
docs(repo): refresh stale CLAUDE.md note, document /demo API, align P…
w7-mgfcode May 18, 2026
c77ab4c
fix(ui): chart series render black — drop hsl() wrapper on oklch char…
w7-mgfcode May 18, 2026
25e0934
fix(jobs): backtest job result keeps fold metrics, stability and base…
w7-mgfcode May 18, 2026
ba901f6
fix(ui): forecast page reads forecasts/forecast from predict job resu…
w7-mgfcode May 18, 2026
ca843c5
fix(registry): tolerate multiple matches in _find_duplicate (#146) (#…
w7-mgfcode May 18, 2026
acfbf72
fix(ui): derive TimeSeriesChart line stroke from the config key (#156…
w7-mgfcode May 18, 2026
2545b95
feat(ui): job picker dropdown on forecast and backtest pages (#154) (…
w7-mgfcode May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@
# These owners will be requested for review when PRs touch their areas
#
# Format: path @username or @org/team
# Note: Replace placeholder usernames with actual GitHub usernames

# Default owners for everything
* @your-username
* @w7-mgfcode

# Core infrastructure
/app/core/ @your-username
/app/core/ @w7-mgfcode

# Feature modules (add specific owners as team grows)
/app/features/ @your-username
/app/features/ @w7-mgfcode

# CI/CD configuration
/.github/ @your-username
/.github/ @w7-mgfcode

# Database migrations
/alembic/ @your-username
/alembic/ @w7-mgfcode

# Documentation
/docs/ @your-username
/docs/ @w7-mgfcode

# Configuration files
/pyproject.toml @your-username
/docker-compose.yml @your-username
/pyproject.toml @w7-mgfcode
/docker-compose.yml @w7-mgfcode
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Documentation
url: https://github.com/your-org/ForecastLabAI/tree/main/docs
url: https://github.com/w7-mgfcode/ForecastLabAI/tree/main/docs
about: Check the documentation before opening an issue
15 changes: 9 additions & 6 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

## Type of Change

- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Refactoring (no functional changes)
- [ ] Documentation update
- [ ] CI/CD changes
<!-- Matches the commit-format type field (.claude/rules/commit-format.md) -->

- [ ] `feat` — new feature
- [ ] `fix` — bug fix
- [ ] `feat!` / `fix!` — breaking change (or `BREAKING CHANGE:` in the body)
- [ ] `refactor` — code restructure, no behavior change
- [ ] `docs` — documentation only
- [ ] `test` — test-only change
- [ ] `chore` / `ci` — tooling, CI, or repo hygiene (no version bump)

## Checklist

Expand Down
131 changes: 131 additions & 0 deletions .github/workflows/e2e-nightly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
name: E2E Demo (nightly)

# Nightly run of `scripts/run_demo.py` against a fresh Postgres+pgvector
# service to catch regressions in the documented end-to-end pipeline
# (seed -> features -> train -> backtest -> register -> verify).
#
# Per PRP-15, this workflow is intentionally NOT a required status check
# on `dev` or `main` -- it is informational only. Flake-budget lives here,
# not in the per-PR `ci.yml` gate.
#
# Trigger options:
# * Daily schedule at 07:00 UTC (cron `0 7 * * *`)
# * On-demand via `workflow_dispatch` (with optional ref override)

on:
schedule:
- cron: '0 7 * * *'
workflow_dispatch:
inputs:
ref:
description: 'Branch or ref to run the nightly demo on (default: github.ref)'
required: false
type: string

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ inputs.ref || github.ref }}
cancel-in-progress: true

env:
PYTHON_VERSION: "3.12"
UV_VERSION: "0.5"
CHECKOUT_REF: ${{ inputs.ref || github.ref }}
# API the script will hit. Bound to localhost because the runner ports
# this nightly job. Mirrors scripts/run_demo.py default.
DEMO_API_URL: "http://127.0.0.1:8123"

jobs:
e2e-demo:
name: Run end-to-end demo
runs-on: ubuntu-latest

services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_USER: forecastlab
POSTGRES_PASSWORD: forecastlab
POSTGRES_DB: forecastlab_e2e
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

env:
DATABASE_URL: postgresql+asyncpg://forecastlab:forecastlab@localhost:5432/forecastlab_e2e
APP_ENV: testing
# The agent step in run_demo.py auto-skips when neither key is set;
# nightly CI runs without LLM keys so the step short-circuits with
# `⏭️ [SKIP]`. Do NOT add OPENAI_API_KEY / ANTHROPIC_API_KEY here.

steps:
- uses: actions/checkout@v6
with:
ref: ${{ env.CHECKOUT_REF }}

- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: ${{ env.UV_VERSION }}
enable-cache: true

- name: Set up Python
run: uv python install ${{ env.PYTHON_VERSION }}

- name: Install dependencies
run: uv sync --frozen --all-extras --dev

- name: Apply migrations
run: uv run --frozen alembic upgrade head

- name: Start uvicorn in background
# We bind to 127.0.0.1:8123 (the script's default) and write logs
# to a file so the artifact upload below can capture them on
# failure for forensics.
run: |
mkdir -p .ci-logs
nohup uv run --frozen uvicorn app.main:app \
--host 127.0.0.1 --port 8123 --log-level warning \
> .ci-logs/uvicorn.log 2>&1 &
echo $! > .ci-logs/uvicorn.pid

- name: Wait for uvicorn /health
run: |
for i in $(seq 1 30); do
if curl -fsS "${DEMO_API_URL}/health" > /dev/null; then
echo "uvicorn ready after ${i}s"
exit 0
fi
sleep 1
done
echo "uvicorn did not become healthy within 30s"
cat .ci-logs/uvicorn.log || true
exit 1

- name: Run demo pipeline
run: |
uv run --frozen python scripts/run_demo.py \
--seed 42 \
--api-url "${DEMO_API_URL}" \
--timeout 60

- name: Stop uvicorn
if: always()
run: |
if [ -f .ci-logs/uvicorn.pid ]; then
kill "$(cat .ci-logs/uvicorn.pid)" || true
fi

- name: Upload uvicorn logs on failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: uvicorn-logs
path: .ci-logs/
retention-days: 7
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.2.8"
".": "0.2.10"
}
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# Changelog

## [0.2.10](https://github.com/w7-mgfcode/ForecastLabAI/compare/v0.2.9...v0.2.10) (2026-05-18)


### Features

* release v0.2.10 — demo showcase page + e2e pipeline ([#134](https://github.com/w7-mgfcode/ForecastLabAI/issues/134)) ([2ea68ae](https://github.com/w7-mgfcode/ForecastLabAI/commit/2ea68ae1b875e48013fe7f09e9850ef648e0f616))

## [0.2.9](https://github.com/w7-mgfcode/ForecastLabAI/compare/v0.2.8...v0.2.9) (2026-05-14)


### Features

* **api,docs:** codify pydantic strict-mode policy as pytest invariant ([#120](https://github.com/w7-mgfcode/ForecastLabAI/issues/120)) ([#121](https://github.com/w7-mgfcode/ForecastLabAI/issues/121)) ([89b197d](https://github.com/w7-mgfcode/ForecastLabAI/commit/89b197dcac4176d1b9585886a3e5b9e4de30ce3f))
* **features,docs:** land phase 2 e2e integration and docs ([#109](https://github.com/w7-mgfcode/ForecastLabAI/issues/109)) ([#115](https://github.com/w7-mgfcode/ForecastLabAI/issues/115)) ([56de87c](https://github.com/w7-mgfcode/ForecastLabAI/commit/56de87c26dc5e0f1e1e7262cf4d09545b42643d7))
* **features:** implement lifecycle compute method ([#109](https://github.com/w7-mgfcode/ForecastLabAI/issues/109)) ([#111](https://github.com/w7-mgfcode/ForecastLabAI/issues/111)) ([902d82a](https://github.com/w7-mgfcode/ForecastLabAI/commit/902d82acb4ccfb0c141f815ea42b427735c99223))
* **features:** implement promotion compute method ([#109](https://github.com/w7-mgfcode/ForecastLabAI/issues/109)) ([#112](https://github.com/w7-mgfcode/ForecastLabAI/issues/112)) ([52f6497](https://github.com/w7-mgfcode/ForecastLabAI/commit/52f6497ea585a5df06d287896cbb52bcceada1e4))
* **features:** implement replenishment compute method ([#109](https://github.com/w7-mgfcode/ForecastLabAI/issues/109)) ([#114](https://github.com/w7-mgfcode/ForecastLabAI/issues/114)) ([b39c940](https://github.com/w7-mgfcode/ForecastLabAI/commit/b39c940d801296a4a3316d1544aa1cb2e1a65ca9))
* **features:** lower ReplenishmentConfig count_window_days floor to 3 ([#113](https://github.com/w7-mgfcode/ForecastLabAI/issues/113)) ([#122](https://github.com/w7-mgfcode/ForecastLabAI/issues/122)) ([42c9fb8](https://github.com/w7-mgfcode/ForecastLabAI/commit/42c9fb86004e93c4a52461a08281dc0d00122698))
* **features:** plumb product attrs through FeatureDataLoader ([#116](https://github.com/w7-mgfcode/ForecastLabAI/issues/116)) ([#118](https://github.com/w7-mgfcode/ForecastLabAI/issues/118)) ([0e41fb3](https://github.com/w7-mgfcode/ForecastLabAI/commit/0e41fb3a41482009038a61cb0c0046d20730ed0d))
* **features:** pydantic configs + PRP set for phase 2 feature wiring ([#109](https://github.com/w7-mgfcode/ForecastLabAI/issues/109)) ([#110](https://github.com/w7-mgfcode/ForecastLabAI/issues/110)) ([f8978c5](https://github.com/w7-mgfcode/ForecastLabAI/commit/f8978c5046189775077ee2840d6c3afd4b985988))
* **release:** cut v0.2.9 with phase 2 e2e + strict-mode + main protection ([#108](https://github.com/w7-mgfcode/ForecastLabAI/issues/108)) ([e71ae39](https://github.com/w7-mgfcode/ForecastLabAI/commit/e71ae395a64b750e5cdca6a2ce9ba27deb909fad))


### Bug Fixes

* **api,agents:** bypass .env in 4 Settings tests ([#104](https://github.com/w7-mgfcode/ForecastLabAI/issues/104)) ([#105](https://github.com/w7-mgfcode/ForecastLabAI/issues/105)) ([dd3a9a7](https://github.com/w7-mgfcode/ForecastLabAI/commit/dd3a9a75c442ede9591e2cf6886cc666cbc7c1b1))
* **forecast,features:** apply strict-mode JSON date policy to request bodies ([#117](https://github.com/w7-mgfcode/ForecastLabAI/issues/117)) ([#119](https://github.com/w7-mgfcode/ForecastLabAI/issues/119)) ([ba7c1c1](https://github.com/w7-mgfcode/ForecastLabAI/commit/ba7c1c1edf2da7eef6b0a67d77ab6868c7ab32e2))


### Documentation

* **docs:** document release-please merge-subject trap ([#102](https://github.com/w7-mgfcode/ForecastLabAI/issues/102)) ([#103](https://github.com/w7-mgfcode/ForecastLabAI/issues/103)) ([9990e57](https://github.com/w7-mgfcode/ForecastLabAI/commit/9990e57a632e7b8a80db752638fc7029147a8363))
* **docs:** verify and remove [unverified] tags in docs/_base ([#106](https://github.com/w7-mgfcode/ForecastLabAI/issues/106)) ([#107](https://github.com/w7-mgfcode/ForecastLabAI/issues/107)) ([7774fbb](https://github.com/w7-mgfcode/ForecastLabAI/commit/7774fbb31c5a0a2539868648264a0ad5196e186b))

## [0.2.8](https://github.com/w7-mgfcode/ForecastLabAI/compare/v0.2.7...v0.2.8) (2026-05-12)


Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,4 @@ wc -l CLAUDE.md # must stay ≤ 150
## Learnings

<!-- Session-specific discoveries Claude should remember. Update sparingly. -->
- HEURISTIC_MODE generated this doc (no `docs/_kB/repo-map/` KB). Run `mapping-repo-context` to upgrade fidelity; sections marked `[UNVERIFIED]` in `docs/_base/` need verification.
- HEURISTIC_MODE generated this doc (no `docs/_kB/repo-map/` KB). Run `mapping-repo-context` to upgrade fidelity; sections marked `[ASSUMPTION]` in `docs/_base/` need verification.
Loading