docs: add corporate network/proxy setup (§9) to AGENTS.md + expand switch-network.sh header

This commit is contained in:
saravanakumardb1 2026-03-19 15:22:14 -07:00
parent 3ef40028ab
commit 710992e69f
2 changed files with 107 additions and 8 deletions

View File

@ -417,7 +417,81 @@ AZURE_BLOB_ACCOUNT_KEY=<account-key>
DEFAULT_PRODUCT_ID=lysnrai
```
## 9. Dependency Graph
## 9. Corporate Network / Proxy Setup
Development happens on a corporate network with a TLS-intercepting proxy. The `NETWORK` env var controls all proxy behavior — **no manual toggling needed**.
### Quick Reference
| Tool | Corporate proxy mechanism | Config location |
| -------------------------- | ------------------------------------------------------------------ | --------------------------------------------- |
| **npm / pnpm** | `NPM_CONFIG_REGISTRY` → JFrog proxy, `NPM_CONFIG_STRICT_SSL=false` | `switch-network.sh` |
| **Node.js** | `NODE_TLS_REJECT_UNAUTHORIZED=0` | `switch-network.sh` |
| **Python (pip)** | `PIP_TRUSTED_HOST`, `http_proxy`/`https_proxy` | `switch-network.sh` |
| **Gradle / Android / KMP** | Custom JVM truststore with corporate CA cert | `~/.gradle/gradle.properties` + `GRADLE_OPTS` |
| **curl / general HTTP** | `http_proxy`/`https_proxy` → `cso.proxy.att.com:8080` | `switch-network.sh` |
### How it works
1. `~/.zshrc` sets `export NETWORK=corp` (or `home`)
2. `~/.zshrc` sources `scripts/switch-network.sh` from this repo
3. The script conditionally sets/unsets all proxy env vars based on `NETWORK`
4. On new shell: `🏢 NETWORK=corp — proxy active` or `🏠 NETWORK=home — direct internet`
### Key files
| File | Purpose |
| -------------------------------------------------------- | ---------------------------------------------------------- |
| [`scripts/switch-network.sh`](scripts/switch-network.sh) | Central network switch — sets all proxy vars |
| `~/.gradle/gradle.properties` | Gradle daemon JVM args (truststore) + HTTP proxy host/port |
| `~/.gradle/ssl/gradle-cacerts.jks` | Java truststore = default cacerts + ATT CSO proxy CA cert |
### Gradle SSL (TLS interception)
The corporate proxy (`cso.proxy.att.com`) does TLS interception — it replaces upstream TLS certificates with its own, signed by the `ATTINTERNALROOTv2` CA. Gradle's JVM doesn't trust this CA by default.
**Solution:** A custom Java truststore (`~/.gradle/ssl/gradle-cacerts.jks`) that includes:
- All default Java CA certificates (from `$JAVA_HOME/lib/security/cacerts`)
- The AT&T CSO proxy CA certificate
The truststore is passed to Gradle via:
- `GRADLE_OPTS` env var (set by `switch-network.sh` when `NETWORK=corp`) — for the wrapper bootstrap JVM
- `org.gradle.jvmargs` in `~/.gradle/gradle.properties` — for the daemon JVM
**Recreate truststore** (needed after Java updates):
```bash
mkdir -p ~/.gradle/ssl
JAVA_HOME=$(/usr/libexec/java_home)
cp "$JAVA_HOME/lib/security/cacerts" ~/.gradle/ssl/gradle-cacerts.jks
echo | openssl s_client -connect services.gradle.org:443 \
-proxy cso.proxy.att.com:8080 -showcerts 2>/dev/null \
| awk 'BEGIN{c=0} /BEGIN CERT/{c++} c==2{print} /END CERT/&&c==2{exit}' \
> /tmp/corp-ca.pem
keytool -importcert -noprompt -trustcacerts -alias att-cso-proxy \
-file /tmp/corp-ca.pem \
-keystore ~/.gradle/ssl/gradle-cacerts.jks -storepass changeit
```
### MUST follow (network-related)
- Always use `NETWORK` env var — never hardcode proxy URLs in app code
- Gradle builds require `GRADLE_OPTS` with truststore when on corp network (handled automatically by `switch-network.sh`)
- If a Gradle build fails with SSL errors, verify `echo $GRADLE_OPTS` shows the truststore path
- If adding a new tool that fetches from the internet, add its proxy config to `switch-network.sh`
- `~/.gradle/gradle.properties` is a local-only file — never commit it to any repo
### Kotlin Platform SDK (`packages/kotlin-platform-sdk/`)
The shared Kotlin SDK is consumed by Android apps as a composite build via `includeBuild()` in each product's `settings.gradle.kts`. Key details:
- `settings.gradle.kts` declares `pluginManagement` and `dependencyResolutionManagement` repos (required for composite builds to resolve their own deps)
- `build.gradle.kts` uses the Compose compiler plugin for UI components (`SurveyUI`, `InAppMessageUI`)
- Uses `kotlinOptions { jvmTarget = "17" }` (not `compilerOptions {}`) for compatibility
## 10. Dependency Graph
```
@bytelyst/errors ← no deps (foundation)
@ -441,7 +515,7 @@ DEFAULT_PRODUCT_ID=lysnrai
Build order: packages first (they have no inter-deps), then services. `pnpm build` handles this automatically via workspace topology.
## 10. Key Documents
## 11. Key Documents
| When you need to... | Read this |
| -------------------------------- | -------------------------------------------------------------------------------------------------- |
@ -452,7 +526,7 @@ Build order: packages first (they have no inter-deps), then services. `pnpm buil
| LysnrAI product repo conventions | [`../learning_voice_ai_agent/AGENTS.md`](../learning_voice_ai_agent/AGENTS.md) |
| MindLyst native repo conventions | [`../learning_multimodal_memory_agents/AGENTS.md`](../learning_multimodal_memory_agents/AGENTS.md) |
## 11. Service Test Counts
## 12. Service Test Counts
| Service / Package | Tests | Runner |
| ------------------ | -------- | ------ |
@ -478,7 +552,7 @@ Product-specific API modules have been migrated from platform-service into each
Each product backend uses `@bytelyst/*` packages via `file:` refs and follows the same Fastify module pattern.
## 12. Common Pitfalls
## 14. Common Pitfalls
1. **Don't import `zod` from `@bytelyst/config` in services** — services bundle their own zod version. Use self-contained Zod schemas in `src/lib/config.ts`.
2. **Don't forget `productId`** — every Cosmos document must include it.

View File

@ -6,15 +6,40 @@
# Controls: one env var — NETWORK=corp or NETWORK=home
#
# Usage (add to ~/.zshrc):
# export NETWORK=corp # at work
# export NETWORK=corp # at work / on VPN
# export NETWORK=home # at home (or just unset it)
#
# Then source this file from ~/.zshrc:
# source "$HOME/code/mygh/learning_ai_common_plat/scripts/switch-network.sh"
#
# What it sets:
# NETWORK=corp → http_proxy, https_proxy, npm/pnpm registry, pip trusted-host
# NETWORK=home → all proxy vars unset, default registries
# What it sets when NETWORK=corp:
# - http_proxy / https_proxy → cso.proxy.att.com:8080
# - NPM_CONFIG_REGISTRY → AT&T JFrog npm proxy
# - NPM_CONFIG_PROXY → corporate proxy
# - NPM_CONFIG_STRICT_SSL → false (proxy TLS interception)
# - NODE_TLS_REJECT_UNAUTHORIZED → 0 (Node.js trusts proxy certs)
# - PIP_TRUSTED_HOST → pypi.org, files.pythonhosted.org
# - GRADLE_OPTS → JVM truststore with corporate CA cert
# (truststore at ~/.gradle/ssl/gradle-cacerts.jks)
#
# What it sets when NETWORK=home:
# - All proxy vars unset, default registries, direct internet
#
# Gradle SSL setup (one-time):
# The corporate proxy (cso.proxy.att.com) does TLS interception.
# Gradle's JVM needs a custom truststore with the proxy CA cert.
# To create/recreate:
# mkdir -p ~/.gradle/ssl
# JAVA_HOME=$(/usr/libexec/java_home)
# cp "$JAVA_HOME/lib/security/cacerts" ~/.gradle/ssl/gradle-cacerts.jks
# echo | openssl s_client -connect services.gradle.org:443 \
# -proxy cso.proxy.att.com:8080 -showcerts 2>/dev/null \
# | awk 'BEGIN{c=0} /BEGIN CERT/{c++} c==2{print} /END CERT/&&c==2{exit}' \
# > /tmp/corp-ca.pem
# keytool -importcert -noprompt -trustcacerts -alias att-cso-proxy \
# -file /tmp/corp-ca.pem \
# -keystore ~/.gradle/ssl/gradle-cacerts.jks -storepass changeit
#
# ─────────────────────────────────────────────────────────────
_CORP_PROXY="http://cso.proxy.att.com:8080/"