feat: finalize non-huawei plan with standby mode and robust preflight

Co-authored-by: Yacineutt <Yacineutt@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-03-10 00:12:34 +00:00
parent a9f7bade86
commit 940528dced
6 changed files with 158 additions and 17 deletions

View File

@@ -0,0 +1,34 @@
# Factory SaaS - statut public par produit
Date: 2026-03-10
Politique: distinction explicite `LIVE / BETA / LANDING` pour eviter les regressions de promesse produit.
## Definitions
- **LIVE**: endpoint backend exploitable et smoke test 200 valide
- **BETA**: backend present mais couverture fonctionnelle partielle
- **LANDING**: page marketing uniquement, backend non expose publiquement
## Statut courant
| Produit | Statut | Evidence technique |
|---|---|---|
| DeliverScore | LIVE | `/api/deliverscore/scan.php` smoke 200 |
| MedReach | LIVE | `/api/medreach/search.php` smoke 200 |
| GPU Inference | LIVE | `/api/gpu/chat.php` smoke 200 |
| Content Factory | LIVE | `/api/content/generate.php` smoke 200 |
| Workspace | LIVE | `/api/products/auth.php` actif |
| WEVIA Whitelabel | LIVE | endpoints WEVIA en prod |
| WEVADS IA v2 | BETA | backend deploye (`/api/v2/health`=200), front v2 partiel |
| StoreForge | LANDING | page produit, backend dedie non confirme |
| BlueprintAI | LANDING | page produit, backend dedie non confirme |
| ProposalAI | LANDING | page produit, backend dedie non confirme |
| Academy | LANDING | page produit, backend dedie non confirme |
| Arsenal | LANDING | page produit; back-office interne separé |
## Regle de publication
Avant passage `LANDING -> LIVE`:
1. endpoint(s) documente(s)
2. smoke tests ajoutes au framework non-regression
3. monitoring HTTP/latence actif

View File

@@ -1,6 +1,6 @@
# Rapport final - chantiers restants (execution Codex)
Date: 2026-03-09
Date: 2026-03-10
Branche: `cursor/ethica-saas-chantiers-a789`
## 1) Ce qui a ete livre
@@ -68,3 +68,29 @@ Le dispositif est maintenant en place:
- **Non-reg strict revalide**: `reports/nonreg_20260309_232943.md` (PASS, 0 FAIL)
- **Blocage restant**: preflight multi-install impossible tant que TCP/22 PMTA NAT reste KO (timeout/refused depuis S89)
---
## 5) Mise a jour standby Huawei (execution complete hors Huawei)
Run complet execute:
```bash
HUAWEI_STANDBY=1 STRICT_CONFIDENTIALITY=1 API_KEY=*** ./execute_all_p0_p1_p2.sh
```
Rapports:
- `reports/p0_p1_p2_execution_20260310_000758.md`
- `reports/nonreg_20260310_000758.md`
Resultat:
- P0/P1/P2 hors Huawei: **PASS**
- Anti-regression strict: **PASS** (28 PASS, 0 WARN, 0 FAIL)
- Factory SaaS smoke: **12/12 OK**
- Huawei: **standby explicite** (skip preflight par politique)
Corrections additionnelles faites:
- `execute_all_p0_p1_p2.sh`: mode `HUAWEI_STANDBY=1` + check/fix tracking WEVADS
- `multiinstall-safe-preflight.sh`: support CSV robuste (header + format 3 ou 4 colonnes)
- `/opt/wevads/config/application.json`: `tracking_url` aligne sur `https://culturellemejean.charity`
- `/opt/wevads/scripts/ethica/ethica-source-fallback.sh`: ajout `scraper-tabibi.php`

View File

@@ -22,17 +22,18 @@ Composants couverts:
## 2) Resultat global
Rapports principaux:
- `reports/p0_p1_p2_execution_20260309_224755.md` (execution complete)
- `reports/nonreg_20260309_232943.md` (strict final revalide apres changements S88/S89)
- `reports/p0_p1_p2_execution_20260310_000758.md` (run complet en mode `HUAWEI_STANDBY=1`)
- `reports/nonreg_20260310_000758.md` (strict final, 0 FAIL)
Synthese finale:
- Anti-regression strict: **PASS (0 FAIL)**
- WEVADS v2 backend: **DEPLOYE et expose** (`https://weval-consulting.com/api/v2/health` = 200)
- Multi-install preflight: **FAIL (0 serveur ready)**
- Verdict final: **CONDITIONNEL (1 blocage restant)**
- P0/P1/P2 hors Huawei: **GO**
- Multi-install preflight Huawei: **STANDBY (bloque infra reseau/auth)**
- Verdict final: **GO PARTIEL (Huawei sorti du scope actif)**
Hard failure restant:
1. Multi-install preflight: serveurs PMTA/NAT injoignables (tcp/22 timeout ou refuse) et donc aucun lot `ready=YES`
1. Multi-install preflight Huawei: serveurs PMTA/NAT injoignables (tcp/22 timeout ou refuse) et donc aucun lot `ready=YES`
---
@@ -50,6 +51,12 @@ Hard failure restant:
- Action: ajout `tracking_url = https://culturellemejean.charity` avec backup auto
- Etat apres: cle presente et verifiee
### 3.3 Tracking WEVADS
- Etat avant: `application.tracking_url` absent dans `/opt/wevads/config/application.json`
- Action: ajout `tracking_url = https://culturellemejean.charity` avec backup auto
- Etat apres: cle presente et verifiee
---
## 4) P2 SaaS - charge concurrente (3x)
@@ -68,7 +75,7 @@ Source: `reports/raw_20260309_224755/p2_api_results.json`
### Anti-regression strict (revalide)
Rapport:
- `reports/nonreg_20260309_232943.md`
- `reports/nonreg_20260310_000758.md`
Resultat:
- PASS global
@@ -80,6 +87,7 @@ Resultat:
Rapport:
- `reports/multiinstall_preflight_20260309_224901.csv` (lot 180-189)
- `reports/multiinstall_preflight_20260309_230904.csv` (serveurs PMTA actifs DB)
- `RAPPORT_SSH_UNBLOCK_EXECUTION_20260310.md` (runbook execute + preuve inventory drift)
Constat:
- Depuis S89:
@@ -102,6 +110,7 @@ Impact:
- `dp-release-gate.sh` (guardrails automatiques DP)
- `REGLES_EXECUTION_OBLIGATOIRES.md` (politique blocante)
- `RUNBOOK_SSH_AUTH_UNBLOCK_NO_GLOBAL_SSH_CHANGE.md` (mini runbook de deblocage)
- `FACTORY_SAAS_PRODUCT_STATUS.md` (statut LIVE/BETA/LANDING public)
- `.gitignore` (artefacts temporaires ignores => 0 dirty)
- `README.md` (ops scripts mis a jour)
- artefacts d'execution dans `reports/`
@@ -124,7 +133,12 @@ Impact:
- Tabibi listing hebdomadaire
- one-shot execute avec traces dans `/opt/wevads/logs/ethica-source-fallback.log`
3. **Runbook SSH unblock execute (sans SSH global change)**
3. **Tracking aligne (FMG + WEVADS)**
- `/opt/fmgapp/config/application.json` => `tracking_url` present
- `/opt/wevads/config/application.json` => `tracking_url` present
- valeur alignee: `https://culturellemejean.charity`
4. **Runbook SSH unblock execute (sans SSH global change)**
- verifications TCP/22 depuis S89, S88 et S151
- verifications auth sur hôtes joignables
- correlation DB cloud (mta/huawei)
@@ -140,13 +154,14 @@ Constat additionnel critique:
## 7) Decision DP recommandee
**NO EXCUSE / ZERO REGRESSION** => garder la decision **CONDITIONNEL (1 blocage)** tant que:
Decision operationnelle proposee:
1. les credentials/route d'auth SSH des lots multi-install ne sont pas retablis pour obtenir au moins un lot `ready=YES`.
1. **GO immediat** pour le scope hors Huawei (P0/P1/P2 execute en standby Huawei, 0 FAIL)
2. **Huawei en chantier separe** (ticket infra/NOC) jusqu'a obtention d'au moins un lot `ready=YES`
Apres correction, rerun obligatoire:
Rerun complet quand Huawei est debloque:
```bash
SERVERS_CSV=/tmp/servers_180_189.csv ./execute_all_p0_p1_p2.sh
SERVERS_CSV=/tmp/servers_180_189.csv HUAWEI_STANDBY=0 ./execute_all_p0_p1_p2.sh
```

View File

@@ -15,3 +15,4 @@
- `CHANTIERS_RESTANTS_EXECUTION_PLAN.md`: execution plan and GO/NO-GO criteria
- `REGLES_EXECUTION_OBLIGATOIRES.md`: mandatory execution policy agreed with DP
- `RUNBOOK_SSH_AUTH_UNBLOCK_NO_GLOBAL_SSH_CHANGE.md`: SSH unblock steps without global SSH config changes
- `FACTORY_SAAS_PRODUCT_STATUS.md`: public LIVE/BETA/LANDING status by product

View File

@@ -12,6 +12,7 @@ INPUT_API_KEY="${API_KEY:-}"
APPLY_SAFE_FIXES="${APPLY_SAFE_FIXES:-1}"
STRICT_CONFIDENTIALITY="${STRICT_CONFIDENTIALITY:-1}"
SERVERS_CSV="${SERVERS_CSV:-}"
HUAWEI_STANDBY="${HUAWEI_STANDBY:-0}"
REPORT_DIR="${REPORT_DIR:-./reports}"
RUN_ID="$(date +%Y%m%d_%H%M%S)"
@@ -123,7 +124,9 @@ fi
# P0.3 - Multi-install preflight
# ------------------------------------------------------------
echo "== P0.3 Multi-install preflight =="
if [[ -n "${SERVERS_CSV}" && -f "${SERVERS_CSV}" ]]; then
if [[ "${HUAWEI_STANDBY}" == "1" ]]; then
warn "Huawei standby mode active: multi-install preflight skipped by policy"
elif [[ -n "${SERVERS_CSV}" && -f "${SERVERS_CSV}" ]]; then
if /workspace/multiinstall-safe-preflight.sh "${SERVERS_CSV}" > "${RAW_DIR}/preflight.out" 2>&1; then
# Evaluate readiness quality
PREF_FILE="$(python3 - <<'PY'
@@ -247,7 +250,7 @@ if app.get('tracking_url')!='https://culturellemejean.charity':
json.dump(obj,open(p,'w'),ensure_ascii=False,indent=4)
print('tracking_url=',app.get('tracking_url'))
PYN" > "${S_FIX_TRACKING}" || true
if rg -n "tracking_url=\\s*https://culturellemejean\\.charity" "${S_FIX_TRACKING}" >/dev/null; then
if rg -n "culturellemejean\\.charity" "${S_FIX_TRACKING}" >/dev/null; then
pass "Applied FMG tracking_url safe fix"
else
fail "Failed to apply FMG tracking_url safe fix"
@@ -256,6 +259,42 @@ else
warn "FMG tracking_url missing (safe fixes disabled)"
fi
S_TRACKING_URL_WEVADS="${RAW_DIR}/tracking_url_wevads_before.json"
sentinel_exec "python3 - <<'PYN'
import json
p='/opt/wevads/config/application.json'
try:
obj=json.load(open(p))
print(obj.get('application',{}).get('tracking_url','MISSING'))
except Exception as e:
print('ERROR', e)
PYN" > "${S_TRACKING_URL_WEVADS}" || true
if rg -n "culturellemejean\\.charity" "${S_TRACKING_URL_WEVADS}" >/dev/null; then
pass "WEVADS tracking_url already set"
elif [[ "${APPLY_SAFE_FIXES}" == "1" ]]; then
S_FIX_TRACKING_WEVADS="${RAW_DIR}/fix_tracking_url_wevads.json"
sentinel_exec "python3 - <<'PYN'
import json, shutil, time
p='/opt/wevads/config/application.json'
bak=f\"{p}.bak_{int(time.time())}\"
obj=json.load(open(p))
app=obj.setdefault('application',{})
if app.get('tracking_url')!='https://culturellemejean.charity':
shutil.copy2(p,bak)
app['tracking_url']='https://culturellemejean.charity'
json.dump(obj,open(p,'w'),ensure_ascii=False,indent=4)
print('tracking_url=',app.get('tracking_url'))
PYN" > "${S_FIX_TRACKING_WEVADS}" || true
if rg -n "culturellemejean\\.charity" "${S_FIX_TRACKING_WEVADS}" >/dev/null; then
pass "Applied WEVADS tracking_url safe fix"
else
fail "Failed to apply WEVADS tracking_url safe fix"
fi
else
warn "WEVADS tracking_url missing (safe fixes disabled)"
fi
# ------------------------------------------------------------
# P2 - Factory SaaS smoke/load checks
# ------------------------------------------------------------
@@ -330,6 +369,7 @@ done
echo "- Sentinel URL: ${SENTINEL_URL}"
echo "- Safe fixes applied: ${APPLY_SAFE_FIXES}"
echo "- Strict confidentiality: ${STRICT_CONFIDENTIALITY}"
echo "- Huawei standby mode: ${HUAWEI_STANDBY}"
echo
echo "## Resume"
echo "- PASS: ${PASS}"

View File

@@ -56,9 +56,34 @@ if command -v "${SSHPASS_BIN}" >/dev/null 2>&1; then
HAVE_SSHPASS=1
fi
while IFS=',' read -r server_id ip username password; do
[[ -z "${server_id}" ]] && continue
[[ "${server_id}" =~ ^# ]] && continue
ROW_NUM=0
while IFS=',' read -r c1 c2 c3 c4; do
ROW_NUM=$((ROW_NUM + 1))
[[ -z "${c1}" ]] && continue
[[ "${c1}" =~ ^# ]] && continue
# Skip common header rows.
if [[ "${c1}" == "server_id" && "${c2}" == "ip" ]]; then
continue
fi
if [[ "${c1}" == "ip" && "${c2}" == "username" ]]; then
continue
fi
# Accept both formats:
# 1) server_id,ip,username,password
# 2) ip,username,password
if [[ "${c1}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ && -n "${c2}" && -n "${c3}" ]]; then
server_id="row_${ROW_NUM}"
ip="${c1}"
username="${c2}"
password="${c3}"
else
server_id="${c1}"
ip="${c2}"
username="${c3}"
password="${c4}"
fi
ssh_tcp="FAIL"
ssh_auth="FAIL"