mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-16 15:40:12 +01:00
feat(web): Core Refactor Phase A — extract sampling and cache modules; add adaptive TTL + eviction heuristics, Redis PoC, and metrics wiring. Tests added for TTL, eviction, exports, splash-adaptive, card index, and service worker. Docs+roadmap updated.
This commit is contained in:
parent
c4a7fc48ea
commit
a029d430c5
49 changed files with 3889 additions and 701 deletions
63
.github/workflows/editorial_governance.yml
vendored
63
.github/workflows/editorial_governance.yml
vendored
|
|
@ -49,4 +49,65 @@ jobs:
|
|||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ratchet-proposal
|
||||
path: ratchet_proposal.json
|
||||
path: ratchet_proposal.json
|
||||
- name: Post ratchet proposal PR comment
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const markerStart = '<!-- ratchet-proposal:description-fallback -->';
|
||||
const markerEnd = '<!-- end-ratchet-proposal -->';
|
||||
let proposal = {};
|
||||
try { proposal = JSON.parse(fs.readFileSync('ratchet_proposal.json','utf8')); } catch(e) { proposal = {error: 'Failed to read ratchet_proposal.json'}; }
|
||||
function buildBody(p) {
|
||||
if (p.error) {
|
||||
return `${markerStart}\n**Description Fallback Ratchet Proposal**\n\n:warning: Could not compute proposal: ${p.error}. Ensure history file exists and job built with EDITORIAL_INCLUDE_FALLBACK_SUMMARY=1.\n${markerEnd}`;
|
||||
}
|
||||
const curTotal = p.current_total_ceiling;
|
||||
const curPct = p.current_pct_ceiling;
|
||||
const propTotal = p.proposed_total_ceiling;
|
||||
const propPct = p.proposed_pct_ceiling;
|
||||
const changedTotal = propTotal !== curTotal;
|
||||
const changedPct = propPct !== curPct;
|
||||
const rationale = (p.rationale && p.rationale.length) ? p.rationale.map(r=>`- ${r}`).join('\n') : '- No ratchet conditions met (headroom not significant).';
|
||||
const testFile = 'code/tests/test_theme_description_fallback_regression.py';
|
||||
let updateSnippet = 'No changes recommended.';
|
||||
if (changedTotal || changedPct) {
|
||||
updateSnippet = [
|
||||
'Update ceilings in regression test (lines asserting generic_total & generic_pct):',
|
||||
'```diff',
|
||||
`- assert summary.get('generic_total', 0) <= ${curTotal}, summary`,
|
||||
`+ assert summary.get('generic_total', 0) <= ${propTotal}, summary`,
|
||||
`- assert summary.get('generic_pct', 100.0) < ${curPct}, summary`,
|
||||
`+ assert summary.get('generic_pct', 100.0) < ${propPct}, summary`,
|
||||
'```' ].join('\n');
|
||||
}
|
||||
return `${markerStart}\n**Description Fallback Ratchet Proposal**\n\nLatest snapshot generic_total: **${p.latest_total}** | median recent generic_pct: **${p.median_recent_pct}%** (window ${p.records_considered})\n\n| Ceiling | Current | Proposed |\n|---------|---------|----------|\n| generic_total | ${curTotal} | ${propTotal}${changedTotal ? ' ←' : ''} |\n| generic_pct | ${curPct}% | ${propPct}%${changedPct ? ' ←' : ''} |\n\n**Rationale**\n${rationale}\n\n${updateSnippet}\n\nHistory-based ratcheting keeps pressure on reducing generic fallback descriptions. If adopting the new ceilings, ensure editorial quality remains stable.\n\n_Analysis generated by ratchet bot._\n${markerEnd}`;
|
||||
}
|
||||
const body = buildBody(proposal);
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
per_page: 100
|
||||
});
|
||||
const existing = comments.find(c => c.body && c.body.includes(markerStart));
|
||||
if (existing) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: existing.id,
|
||||
body
|
||||
});
|
||||
core.info('Updated existing ratchet proposal comment.');
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body
|
||||
});
|
||||
core.info('Created new ratchet proposal comment.');
|
||||
}
|
||||
49
.github/workflows/preview-perf-ci.yml
vendored
Normal file
49
.github/workflows/preview-perf-ci.yml
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
name: Preview Performance Regression Gate
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- 'code/**'
|
||||
- 'csv_files/**'
|
||||
- 'logs/perf/theme_preview_warm_baseline.json'
|
||||
- '.github/workflows/preview-perf-ci.yml'
|
||||
|
||||
jobs:
|
||||
preview-perf:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
PYTHONUNBUFFERED: '1'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
- name: Launch app (background)
|
||||
run: |
|
||||
python -m uvicorn code.web.app:app --host 0.0.0.0 --port 8080 &
|
||||
echo $! > uvicorn.pid
|
||||
# simple wait
|
||||
sleep 5
|
||||
- name: Run preview performance CI check
|
||||
run: |
|
||||
python -m code.scripts.preview_perf_ci_check --url http://localhost:8080 --baseline logs/perf/theme_preview_warm_baseline.json --p95-threshold 5
|
||||
- name: Upload candidate artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: preview-perf-candidate
|
||||
path: logs/perf/theme_preview_ci_candidate.json
|
||||
- name: Stop app
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f uvicorn.pid ]; then kill $(cat uvicorn.pid) || true; fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue