Initial commit: grok-free-register-oss
Open-source Grok free registration CLI, xai_enroller auth pipeline, local auth service, tests and docs.
This commit is contained in:
commit
d10009d639
72 files changed
+18752
No files matched your search
@@ -0,0 +1,180 @@
|
||||
# CSP 架构说明
|
||||
|
||||
本文档记录当前运行时架构。README 面向使用者;本文面向维护者,重点是并发边界、资源生命周期和测试不变量。
|
||||
|
||||
## 目标
|
||||
|
||||
运行时采用 CSP 风格的异步流水线:
|
||||
|
||||
- `S_Worker` 生产 `T`。
|
||||
- `P_Worker` 发起外部请求,等待并生产 `Q`。
|
||||
- `C_Worker` 原子获取一组 `T + Q` 并执行最终消费。
|
||||
|
||||
架构目标是资源所有权闭合、背压边界清晰、取消语义可测试。当前设计不包含中心调度器、动态角色选择或运行时动态并发分配。
|
||||
|
||||
## 核心组件
|
||||
|
||||
`Physical_Sem` 限制本地浏览器重操作并发。`P_Worker` 发出请求后,在等待 `Q` 返回期间不得持有该许可。
|
||||
|
||||
`T_Slot_Sem` 限制已入库 `T` 的容量。`T` 生成成功后才允许获取 slot。
|
||||
|
||||
`Q_Slot_Sem` 限制已返回并入库 `Q` 的容量。`Q` 真正返回前不得获取 slot。
|
||||
|
||||
`Q_Pending_Sem` 限制已发出但尚未终态的外部 `Q` 请求数量。
|
||||
|
||||
`Inventory` 是唯一库存门面。worker 不直接访问底层队列,只能调用:
|
||||
|
||||
```text
|
||||
put_t(env)
|
||||
put_q(env)
|
||||
claim_pair()
|
||||
```
|
||||
|
||||
`ResourceEnvelope` 把资源实体和库存 slot 绑定在一起。slot 只能释放一次。
|
||||
|
||||
`PairLease` 是 `claim_pair()` 返回的异步上下文管理器。pair 一旦 claim 成功,两个 envelope 的所有权转移给 lease,直到 consumer 退出上下文。
|
||||
|
||||
`AdmissionGate` 是局部生产准入门控,只根据库存深度和静态水位决定是否允许继续生产。它不选择 worker 角色,不搬运资源,不调整并发容量。
|
||||
|
||||
## Worker 流程
|
||||
|
||||
### S_Worker
|
||||
|
||||
1. 等待 `AdmissionGate` 允许生产 `T`。
|
||||
2. 获取 `Physical_Sem`。
|
||||
3. 生产 `T`。
|
||||
4. 释放 `Physical_Sem`。
|
||||
5. 调用 `ResourceEnvelope.create_with_slot(...)`,创建 envelope 并获取 `T_Slot_Sem`。
|
||||
6. 调用 `Inventory.put_t(...)`,把所有权转移给 `Inventory`。
|
||||
7. 所有权转移前如果异常或取消,释放已获取的 slot。
|
||||
|
||||
slot 获取和 envelope 创建必须绑定,避免取消落在“已获取 slot、尚未创建 envelope”的窗口。
|
||||
|
||||
### P_Worker
|
||||
|
||||
1. 等待 `AdmissionGate` 允许生产 `Q`。
|
||||
2. 获取 `Q_Pending_Sem`。
|
||||
3. 获取 `Physical_Sem`。
|
||||
4. 创建请求并发送。
|
||||
5. 释放 `Physical_Sem`。
|
||||
6. 在不持有 `Physical_Sem` 的情况下等待 `Q` 返回。
|
||||
7. `Q` 返回后调用 `ResourceEnvelope.create_with_slot(...)`,创建 envelope 并获取 `Q_Slot_Sem`。
|
||||
8. 调用 `Inventory.put_q(...)`,把所有权转移给 `Inventory`。
|
||||
9. 请求进入终态后释放 `Q_Pending_Sem`。
|
||||
|
||||
`Q_Pending_Sem` 表达外部在途上限;`Q_Slot_Sem` 只表达已返回库存容量。两者不能合并。
|
||||
|
||||
### C_Worker
|
||||
|
||||
1. 进入 `async with inventory.claim_pair() as pair`。
|
||||
2. 获取 `Physical_Sem`。
|
||||
3. 消费 pair。
|
||||
4. 释放 `Physical_Sem`。
|
||||
5. 退出 `PairLease`,释放两个库存 slot。
|
||||
|
||||
`C_Worker` 不允许先取单边资源再等待另一边。对 consumer 来说,pair claim 必须是原子的。
|
||||
|
||||
## Inventory 语义
|
||||
|
||||
第一版 `Inventory` 使用一把 lock 和一个 condition。lock 保护等待、复查、过期清理和弹出操作。
|
||||
|
||||
必须保持以下语义:
|
||||
|
||||
- 等待中的 consumer 不移除资源。
|
||||
- claim 成功时同时移除一个有效 `T` 和一个有效 `Q`。
|
||||
- 等待 pair 时被取消,不影响库存。
|
||||
- claim 成功后被取消,由 `PairLease` 核销两个 envelope。
|
||||
- worker 永远不能直接操作底层 `T` / `Q` 队列。
|
||||
|
||||
只要锁内逻辑保持很小,除 lazy expiry cleanup 外基本是 O(1),单锁在当前版本可以接受。只有 profile 证明锁竞争成为真实瓶颈时,才考虑拆锁或分片。
|
||||
|
||||
## 过期模型
|
||||
|
||||
`ResourceEnvelope` 可以携带 `created_at` 和 `expires_at`。`Inventory` 在配对前可以丢弃已过期资源。
|
||||
|
||||
当前采用 lazy cleanup:
|
||||
|
||||
- `put_t`、`put_q`、`claim_pair` 被触发时顺手清理。
|
||||
- 清理会释放它看到的过期 envelope 对应 slot。
|
||||
- 系统完全静默时不会主动扫库。
|
||||
- 单边长期故障和静默停摆由监控暴露,不靠后台 sweeper 修复。
|
||||
|
||||
当前不做 worker 级回队。消费失败后,已 claim 的 `T` 和 `Q` 都由 `PairLease` 核销。
|
||||
|
||||
## 容量策略
|
||||
|
||||
容量边界由 Semaphore 表达。启动期容量优先级:
|
||||
|
||||
```text
|
||||
显式 PHYSICAL_CAP > CAPACITY_PROFILE > CPU/内存自动派生
|
||||
```
|
||||
|
||||
`CAPACITY_PROFILE` 只在启动时读取,是静态 profile,不是运行时调度器。
|
||||
|
||||
默认 worker 数量由容量派生:
|
||||
|
||||
```text
|
||||
S_WORKERS = Physical_Sem + 2
|
||||
P_WORKERS = Q_Pending_Sem + 2
|
||||
C_WORKERS = Physical_Sem + 2
|
||||
```
|
||||
|
||||
worker 数量不是主要调参入口。主要并发边界是各类容量许可,而不是 coroutine 循环数量。
|
||||
|
||||
## 当前不做
|
||||
|
||||
当前版本明确不包含:
|
||||
|
||||
- 中心调度器;
|
||||
- 运行时角色选择;
|
||||
- 动态打分;
|
||||
- 动态并发控制;
|
||||
- worker 级回队;
|
||||
- 高价值资源抢救策略;
|
||||
- 后台过期清扫;
|
||||
- 自动切换高风险浏览器模式。
|
||||
|
||||
这些方向可以单独实验,但不能混入基础所有权模型。
|
||||
|
||||
## 必须保持的不变量
|
||||
|
||||
实现和测试必须维持以下不变量:
|
||||
|
||||
- 每个已获取的库存 slot 最终释放一次且只释放一次。
|
||||
- 每个已准入的 pending 请求最终释放一次 `Q_Pending_Sem`。
|
||||
- `P_Worker` 等待 `Q` 返回时不持有 `Physical_Sem`。
|
||||
- `Q_Slot_Sem` 只在 `Q` 返回后获取。
|
||||
- `C_Worker` 只能通过 `Inventory.claim_pair()` 获取 `T` 和 `Q`。
|
||||
- `claim_pair()` 要么返回一个受 `PairLease` 保护的完整 pair,要么不返回资源。
|
||||
- 等待 pair 时取消,不移除库存资源。
|
||||
- claim pair 后取消,两个 envelope 由 `PairLease` 释放。
|
||||
- 触发清理时,过期资源不能被配对。
|
||||
- 监控只读,不修改 Semaphore、队列或 worker 状态。
|
||||
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
.venv/bin/pip install -r tests/requirements.txt
|
||||
```
|
||||
|
||||
快速检查:
|
||||
|
||||
```bash
|
||||
python3 -m unittest tests.test_admission_gate tests.test_register_runtime_unittest tests.test_inventory_unittest tests.test_runtime_log_analyzer -v
|
||||
```
|
||||
|
||||
完整测试:
|
||||
|
||||
```bash
|
||||
python3 -m pytest tests -q
|
||||
```
|
||||
|
||||
重点测试文件:
|
||||
|
||||
- `tests.test_inventory_unittest`:库存、过期和 lease 行为。
|
||||
- `tests.test_register_runtime_unittest`:worker 运行语义和监控行。
|
||||
- `tests.test_admission_gate`:局部门控水位。
|
||||
- `tests.test_runtime_log_analyzer`:日志解析兼容性。
|
||||
- `tests/test_cancel.py`:取消边界。
|
||||
- `tests/test_property.py`:随机化不变量检查。
|
||||
- `tests/test_stress.py`:更高并发 fake-service 压测。
|
||||
@@ -0,0 +1,67 @@
|
||||
# 本地认证服务
|
||||
|
||||
认证服务把已有的 SSO 会话转换为 CPA 可直接读取的 OAuth 凭据。注册与认证可以在同一台机器,也可以分开运行。
|
||||
|
||||
## 默认同机运行
|
||||
|
||||
同一个项目目录已经或正在运行注册服务时,直接启动认证:
|
||||
|
||||
```bash
|
||||
bash auth-service.sh
|
||||
```
|
||||
|
||||
未配置 SSH 主机时,认证服务自动读取本项目 `keys/` 中的完整会话与历史账号。注册可以继续追加,认证服务只安装经过校验的完整快照。
|
||||
|
||||
## 配置远端同步
|
||||
|
||||
先把无密码导出器放到服务器项目目录:
|
||||
|
||||
```bash
|
||||
scp scripts/export_registered_sessions.py user@server.example:/opt/grok-free-register/scripts/
|
||||
```
|
||||
|
||||
在本地终端设置连接信息:
|
||||
|
||||
可以直接 `export`,也可以把 `.env.example` 复制为 `.env` 后填写;认证入口会自动读取 `.env`。
|
||||
|
||||
```bash
|
||||
export XAI_AUTH_SERVICE_SSH_HOST=user@server.example
|
||||
export XAI_AUTH_SERVICE_SSH_IDENTITY=/path/to/key.pem
|
||||
export XAI_AUTH_SERVICE_REMOTE_ROOT=/opt/grok-free-register
|
||||
```
|
||||
|
||||
使用 `ssh-agent` 时可省略 `XAI_AUTH_SERVICE_SSH_IDENTITY`。
|
||||
|
||||
设置了 `XAI_AUTH_SERVICE_SSH_HOST` 后,默认的 `auto` 模式会选择 SSH。需要明确覆盖时使用:
|
||||
|
||||
```bash
|
||||
export XAI_AUTH_SERVICE_SOURCE=local # 强制读取同机注册结果
|
||||
export XAI_AUTH_SERVICE_SOURCE=ssh # 强制使用 SSH,必须配置主机
|
||||
```
|
||||
|
||||
## 运行
|
||||
|
||||
```bash
|
||||
bash auth-service.sh
|
||||
```
|
||||
|
||||
首次运行会自动安装项目依赖。该命令在当前终端持续运行并直接接受控制命令;输入 `q` 或按 `Ctrl-C` 停止,再次执行同一命令即可重启。不需要额外的会话管理工具。
|
||||
|
||||
普通模式只在来源连接、发现新账号、任务开始、认证结果、限流和控制状态变化时输出。查看队列、重试、节拍和冷却探针时使用:
|
||||
|
||||
```bash
|
||||
bash auth-service.sh --debug
|
||||
```
|
||||
|
||||
运行中终端底部会保持 `认证> ` 输入行。日志更新不会清掉尚未提交的内容;直接输入命令并回车:
|
||||
|
||||
```text
|
||||
s 查看状态
|
||||
take N 取用 N 个凭据
|
||||
p 暂停
|
||||
r 恢复
|
||||
c 取消当前任务
|
||||
q 安全退出
|
||||
```
|
||||
|
||||
快照默认每 30 秒更新一次;内容无变化时终端保持安静。有效快照和已生成凭据会在重启后继续使用。
|
||||
@@ -0,0 +1,19 @@
|
||||
# 凭据库存与取用
|
||||
|
||||
认证成功的凭据保存在本地认证目录,并在 SQLite 库存中维护三种状态:
|
||||
|
||||
- `available`:已经认证、尚未取用;
|
||||
- `claiming`:正在移动到取用批次;
|
||||
- `claimed`:已经取用。
|
||||
|
||||
运行认证服务后输入:
|
||||
|
||||
```text
|
||||
take 100
|
||||
```
|
||||
|
||||
服务会选择最新的 100 个可用凭据,移动到 `claimed/<batch-id>/`,再把对应库存标记为 `claimed`。认证 ledger 中的 `imported` 记录仍然保留,所以这些账号不会被重新认证。
|
||||
|
||||
每条库存记录预留 `note` 字段,默认为空。取用操作不要求填写用途;以后需要备注时可直接更新该字段。
|
||||
|
||||
若文件移动中断,服务下次启动会恢复 `claiming` 状态。库存不足或凭据文件缺失时,操作失败但认证服务继续运行。
|
||||
@@ -0,0 +1,54 @@
|
||||
# 注册教程
|
||||
|
||||
## 开始运行
|
||||
|
||||
```bash
|
||||
git clone <your-fork-or-mirror>/grok-free-register.git
|
||||
cd grok-free-register
|
||||
bash start.sh
|
||||
```
|
||||
|
||||
首次运行会安装 Python、CloakBrowser Chromium 及其系统依赖,然后引导选择邮箱模式。以后再次执行 `bash start.sh` 会直接使用已有配置。
|
||||
|
||||
普通模式只显示服务启动、任务开始、注册成功或失败、本次运行平均速率、累计数量和限流状态。查看完整并发、库存和阶段耗时时使用:
|
||||
|
||||
```bash
|
||||
bash start.sh --debug
|
||||
```
|
||||
|
||||
常用参数:
|
||||
|
||||
```bash
|
||||
bash start.sh --target 100
|
||||
bash start.sh --max-mem 6G
|
||||
bash start.sh --reconfig
|
||||
```
|
||||
|
||||
未设置 `--target` 时服务持续运行,按 `Ctrl-C` 安全停止。
|
||||
再次执行 `bash start.sh` 即可重启。程序直接使用当前终端,不需要额外的会话管理工具。
|
||||
|
||||
## 配置邮箱
|
||||
|
||||
临时邮箱无需额外配置:
|
||||
|
||||
```env
|
||||
EMAIL_MODE=tempmail
|
||||
```
|
||||
|
||||
自建邮箱需要可接收邮件的域名和本项目的收信服务:
|
||||
|
||||
```env
|
||||
EMAIL_MODE=custom
|
||||
EMAIL_DOMAIN=example.com
|
||||
EMAIL_API=http://127.0.0.1:8080
|
||||
```
|
||||
|
||||
自建模式还需运行:
|
||||
|
||||
```bash
|
||||
bash start.sh --email-service
|
||||
```
|
||||
|
||||
性能参数默认会根据 CPU 和可用内存估算。除非正在压测,否则保持 `.env.example` 中的默认值即可。
|
||||
|
||||
成功结果写入 `keys/accounts.txt`、`keys/grok.txt` 和 `keys/auth-sessions.jsonl`;这些文件默认不提交到 Git。
|
||||
@@ -0,0 +1,38 @@
|
||||
# 运行状态与排障
|
||||
|
||||
## 普通模式
|
||||
|
||||
普通模式的每一行都对应一次状态变化:
|
||||
|
||||
- `[→]`:新任务开始;
|
||||
- `[✓]`:任务成功或来源连接完成;
|
||||
- `[✗]`:当前任务失败或被跳过;
|
||||
- `[⏸]`:进入限流冷却或服务暂停;
|
||||
- `[▶]`:限流解除或服务恢复;
|
||||
- `[!]`:来源、配置或流水线出现需要关注的问题。
|
||||
|
||||
认证端输入 `s` 可查看运行状态、待处理数量、当前阶段、本次运行平均速率、累计成功、可用和已取用凭据,以及是否处于限流。
|
||||
|
||||
## Debug 模式
|
||||
|
||||
注册端:
|
||||
|
||||
```bash
|
||||
bash start.sh --debug
|
||||
```
|
||||
|
||||
认证端:
|
||||
|
||||
```bash
|
||||
bash auth-service.sh --debug
|
||||
```
|
||||
|
||||
注册 Debug 面板包含 T/Q 库存、物理并发、S/P/C 阶段耗时和 token 求解时间。认证 Debug 状态包含 source/prepared/completion 队列、重试、授权节拍、冷却、单次探针和近五分钟滚动速率。
|
||||
|
||||
## 常见状态
|
||||
|
||||
限流后不会持续重试。认证端默认等待 60 秒,再只放行一个恢复探针;探针仍被限流时重新等待。注册端同样通过全局冷却闸门阻止并发任务漏过等待周期。
|
||||
|
||||
远端来源暂时断开时,本地认证服务继续使用上一份完整有效快照。恢复连接后会自动同步,不需要重启。
|
||||
|
||||
配置错误会指出缺少或非法的配置名,不输出 traceback。按提示检查 [注册配置](registration.md#配置邮箱) 或 [认证同步配置](auth-service.md#配置远端同步)。
|
||||
Reference in new issue
Block a user