下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/meanful--graduate-job-hunter.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @meanful/graduate-job-hunter。毕业生求职搜索助手(找工作/求职/校招/应届生/就业/秋招/春招)。说一句「帮我找 XX 城市的 XXX 岗位」,它就从全网搜出匹配的校招 / 应届岗位,并直接给出可点击、可直达投递的官方链接。自动剔除社招岗位。技能内置一份 「企业校招入口注册表」(references/company-entrypoints.json),已经把一大批知名企业的 2026 / 2027 校招入口网址 整理好了——你不用再一家家去搜「XX 校招官网在哪」,技能出报告时会直接调用。
能听懂岗位方向、城市、行业、届别偏好,三路搜岗(联网搜索+公司校招官网直查+聚合站线索),输出公司/岗位/城市/投递链接清单,可选生成五区格式单文件 HTML 求职报告;支持建立个人求职档案做长期监控与可选定时任务。当用户说「帮我找工作」「找工作」「求职」「求职季」「毕业季」「就业」「校招」「秋招」「春招」「校招季」「应届生」「毕业生」「工作机会」「岗位」「offer」「宣讲会」「实习转正」「搜校招岗位」「帮我搜某城市的某岗」「最近有什么应届岗」「建求职档案」「更新我的求职监控」时使用。
阅读全文 (展开查看完整说明)
概述
校招岗位深链发现(campus-search-daily)
本技能的成功判据是「正确的职位详情 URL」 —— 不是"有 URL 就算成功"。
必须企业 ↔ 岗位 ↔ URL 三者正确对应;错误岗位混入日报 = 技能失败。
找到公司招聘首页、找到校园招聘首页、搜索引擎出现公司职位、页面出现「招聘职位」字样、
AI 推测存在某岗位 —— 以上全部不算找到岗位。
0. 引用索引(包内文件地图)
仅 SKILL.md 为加载入口;references/ 按需读取、禁嵌套跳转。单一权威·按对象分源(判据=换项目是否仍适用):平台知识→包内;本项目数据→盘上,包内只写路径。
| 文件 | 用途 |
|---|---|
scripts/ats_registry.json + ats_registry.py | ★ ATS 注册表 + 指纹表唯一权威(家族→提取器映射、「识别≠支持」双状态、端点模板) |
scripts/discover_entry.py | ★ 入口发现三级法的机器实现(靶向诊断「真职位板在哪 / 接口在哪」) |
scripts/_evidence_defs.py | ★ 证据分级 EV0–EV5 + DL0–DL5 + DLV1–DLV5 + dl_level→deep_link 唯一降维映射 + QC11 + 非否定守卫 + Prior-Art 前置闸唯一真源 |
scripts/discover_deeplink.py | ★ 深链自动发现探针(Stage A 静态 + Stage C 运行时捕获,只出事实不留判定) |
references/33-岗位深链自动发现机制.md | ★ 深链发现方法论唯一总纲(六阶段 A~F / DL0–DL5 / DLV1–DLV5 / 四条禁令 / 发现即转验证 / ★降维映射 / 华为实证) |
scripts/llm_semantic.py | ★ LLM 语义判断段(作用域硬闸 + 首轮上限 300 + 达上限落盘不判死) |
references/27-宪法全本-八铁律.md | §2 宪法(两总铁则 + 八铁律) |
references/16-入口发现.md | 入口发现三级法唯一权威框架(含「门户页假提取」识别) |
references/17-深链捕获配方.md | 深链配方权威本(家族速查表、配方 A/B/B-2/五/五-B/六、J-1~J-4、战果) |
references/26-采集引擎细则.md | §5(四级梯子 T0–T3 + 执行器返回契约 + 反爬 L1~L4) |
references/25-单企业流程细则.md | §9(九步法 + 判据四层字段组 + title_usable 词表 + method 枚举) |
references/32-LLM语义判断规格.md | LLM 语义判断唯一权威本(白/黑名单、预算 300、达上限四约束、非否定分类) |
references/30-校招日报规格书.md | 报告格式唯一权威 + QC0–QC10 全表 |
references/28-开工自检与环境.md | 开工自检清单 + 环境准备 |
references/22-报告渲染与出厂细则.md | 第 4~7 步细则(QC 全表已降为指针 → 权威见 references/30) |
references/24-国际ATS端点表.md | 国际 ATS 端点形态速查(Greenhouse/Lever/Ashby/SmartRecruiters/SuccessFactors/Taleo/Teamtailor/Workable…) |
references/23-51job.md | 51job 四形态 + coapi API + WAF/过期判据 |
references/29-radancy-ats.md | Radancy 规格(L3 纯 HTTP;meta 总数/翻页) |
references/00-校招岗位抓取总流程.md | 通用入口流程(先搜索后抓取、先 API 后 DOM) |
references/01-phenom-ats.md | Phenom(phApp.ddo 数据岛,翻页 from) |
references/02-已验证校招入口清单.md | 已验证入口清单(持续更新) |
references/03-oracle-orc.md | Oracle ORC(hcmRestApi,本项目已实测) |
references/04-moka-ats.md | Moka(api.mokahr.com 明文 API,orgId 三形态) |
references/05-workday-cxs-api.md | Workday CXS(POST /wday/cxs/) |
references/06-cec-group-platform.md | CEC 中国电子集团(自研 Vue SPA) |
references/07-beisen-zhiye-ats.md | 北森(GetJobAdPageList,两代打法) |
references/08-feishu-ats.md | 飞书招聘(捕获-重放 v3) |
references/09-dayee-hotjob-ats.md | 大易 Wintalent(listPosition API) |
references/10-playwright-cli.md | playwright-cli 辅助抓取法 |
references/11-crc-runjob-ssdp.md | 华润 runjob SSDP 自研系统 |
references/12-moseeker-ats.md | 仟寻 Moseeker(SSR 内嵌 JSON) |
references/13-⑤-B离场闸口.md | ⑤-B 离场闸口(纪律 A + 纪律 B) |
references/14-SPA点击链逆向.md | SPA「点击链逆向 + 参数直达」法 |
references/15-自研站HTTP直取.md | 自研站「HTTP 直取」判据与接口发现三法 |
references/18-入口核对.md | 入口核对方法论(历史参考) |
references/31-career-ops-采纳方法.md | 采纳自 career-ops 的外部方法(方法1 封顶 / 方法3 append-only) |
references/90-坑清单案例全本.md | 坑 1~88 全本(成因/实证/数字) |
references/91-待验台账.md | 待验登记唯一权威簿(V1~V9) |
references/student-profiles.md | ★ Student Profile 契约(A/B/C 占位、字段结构;真实词表真源=Workspace 参数卡/<池名>.md) |
references/keyword-expansion.md | 中→英→市场表达的关键词扩展词表(一次性扩展,不回写 Profile) |
references/report-format.md | City-first / 学生标签 / 措辞契约(报告结构唯一权威仍是 references/30,本文件不构成第二真源) |
launcher.py | ★ 唯一生产入口(--workspace / CSD_WORKSPACE / schema 校验 / capability 诊断) |
_paths.py | ★ 唯一路径真源(SKILL_ROOT/ENGINE_ROOT/SCRIPTS_ROOT/WORKSPACE_ROOT 严格分离) |
engine/ | ★ 编排层(v2_pipeline / orchestrator / scan_all / param_card / job_state / generic_discovery / adapter_hub / reverify_moka / build_report + JS runner) |
engine/selfcheck.py | ★ 分层自检 C0–C4(Package Integrity / Import Isolation / Minimal Workspace / Offline Logic / Runtime Capability) |
references/setup-guide.md | 依赖安装(隔离 venv、来源、验证、卸载) |
scripts/{qc_gate,verify_entries,validate_jobs,check_environment}.py | QC 闸 / 入口探活 / schema 校验 / 依赖自检 |
scripts/llm_semantic.py | LLM 语义判断段(prepare/apply/validate/scope 四子命令) |
scripts/check_refs.py | 引用完整性校验(SKILL.md 全部 references/ 引用可解析) |
scripts/extractors/_ex_*.js|.py + http_sites.json | 各家族提取器(包内唯一权威,盘上不得留副本) |
skill-dependencies.json | 依赖与功能映射(schema v1) |
0.1 包内外界线(判定权归包内,编排权归盘上)
| 归属 | 内容 | 特征 |
|---|---|---|
包内 · 判据层(scripts/,随包走) | ats_registry.{json,py}(家族判定)/_status_defs.py(状态判定)/_evidence_defs.py(证据判定 + DL/DLV/降维映射/前置闸)/discover_entry.py(入口发现)/discover_deeplink.py(深链发现探针)/qc_gate.py(闸门)/verify_entries.py(探活)/verify_deeplinks.py(深链验证事实)/_ex_*.js|.py(提取) | 平台知识 + 判据 —— 换任何项目均适用 |
包内 · 编排层(engine/,随包走) | v2_pipeline/orchestrator/scan_all/param_card/job_state/generic_discovery/adapter_hub/reverify_moka/build_report + verify_links.js/browser_run.js | 编排 —— 路径由 _paths.py 注入,不含项目数据 |
| Workspace(用户项目数据,绝不入包) | 台账 CSV、参数卡/、_scan/、岗位筛选/、结果 CSV、报告 HTML | 项目数据 + 输出 —— 经 --workspace / CSD_WORKSPACE 解析 |
纪律:
scan_all.classify()只消费不定义 —— 第 0 行调ats_registry.family_of(host),未命中才走既有 if-else。禁止在包外新增家族映射(会重现「换盘丢知识」)。
活数据单点(本包只写路径,内容一律以盘上文件为准,不得拷贝进包):
| 活数据 | 路径(相对项目根) |
|---|---|
| 企业台账(动态数量) | 校招目标企业清单_最终版.csv |
| 参数卡(关键词/城市/排序,唯一筛选依据) | 参数卡/YYZ.md、参数卡/LQP.md |
| 扫描结果十三态 / 扫描记录 | 岗位筛选/结果_全场.csv、岗位筛选/扫描记录.csv |
| 原始层落盘(唯一事实源) | _scan/NNN_企业.json |
| 入口发现产物 | _scan/entry_discovery/NNN_企业.json(discover_entry.py 产出) |
| 报告输出 | YYZ/YYZ校招报告_YYYY-MM-DD.html、LQP/LQP校招报告_YYYY-MM-DD.html |
Workspace 根由 --workspace → CSD_WORKSPACE → 满足 schema 的 CWD 依次解析;无法确定时显式失败(禁止静默回落到 Skill 安装目录)。state_engine.py 为历史脚本,已脱离生产链(OBSOLETE),既不在包内、也不在 Workspace 契约内。
0.2 工程任务强制验收闭环(contract-to-production-acceptance)
本包的每次工程任务(缺陷修复 / 能力新增或变更 / 按冻结规范验收 / 交付前检查)必须按用户级技能 contract-to-production-acceptance(与本包同根目录)的A–G 闭环执行:A 建立规范基线(AC 台账)→ B 追踪真实数据流与生产调用链 →C 追踪关键证据 → D 明确验证矩阵(单元测试 / 生产接线 / 真实运行 / 业务结果四类分别验证,不得互相替代)→ E 区分未完成原因(输入不足 / 实现或接线缺失 /路径已运行但业务条件不满足 / 证据不足,禁止统一写"已完成")→ F 自主实施与控制范围(仅学生业务口径、正式规范变更、证据标准变化、产品承诺变化提交授权请求;新问题按阻断性 / 风险 / 授权范围分诊,禁止自动扩批)→ G 正式交付检查。
交付前必须实跑门禁(门禁输出 PASS / FAIL / NOT_RUN / INSUFFICIENT_EVIDENCE四态;FAIL 或 INSUFFICIENT_EVIDENCE 不得交付;NOT_RUN 项必须在验收报告登记):
python <技能根>/contract-to-production-acceptance/scripts/delivery_gate.py --root <本包根> [--workspace <WS>] [--report <验收报告.md>] [--tests-log <run_all_tests.py 输出>] [--run-selfcheck]可选提交门禁(git 层机械阻断):cp <技能根>/contract-to-production-acceptance/scripts/git-pre-commit .git/hooks/pre-commit。
1. 指令层契约(V2 合并层)
本节是会话契约:规定「理解什么要搜、搜哪些范围、如何组织搜索、如何匹配、如何报告」。
「怎样找到网页 / ATS / 岗位 / 深链 / 状态 / 去重」由
engine/(编排)与scripts/(判据)承担。详细规则见
references/student-profiles.md、references/keyword-expansion.md、references/report-format.md。
1.1 生产入口(唯一)
python launcher.py v2 --workspace <WS> --request "上海有哪些 HR 校招"
python launcher.py scan --workspace <WS> --mode full
python launcher.py report --workspace <WS> --date YYYY-MM-DD
python launcher.py selfcheck --level all
python launcher.py caps- 唯一 path 真源:
_paths.py(SKILL_ROOT/ENGINE_ROOT/SCRIPTS_ROOT/WORKSPACE_ROOT严格分离)。 - Workspace 解析优先级:
--workspace→CSD_WORKSPACE→ 满足 schema 的 CWD → 显式失败。 - 缺输入必须失败;禁止创建空 CSV / 空参数卡 / 空结果冒充成功。
engine/*.py的main()仍可调用,但不是 canonical production entry。
1.2 职责边界
Skill 负责七件事:① 理解用户请求 ② 读取 Student Profile ③ 构造 Search Request / Search Scope④ 决定搜索模式 ⑤ 调度 engine ⑥ 多学生 JobMatch ⑦ 生成 City-first 报告。
1.3 Student Profile(长期配置,只读)
- 使用
Student A/Student B占位,禁止硬编码真实姓名。 - 词表唯一真源 = Workspace
参数卡/<池名>.md(经engine/param_card.py读取)。 - 缺 card →
PROFILE_UNAVAILABLE,不得自动读取本机旧 card 或创建空 card。 - 本次请求的临时覆盖只改 Search Request,不回写 Profile。
1.4 搜索模式与实现状态(能力透明)
| 模式 | 状态 |
|---|---|
| Company-driven | SUPPORTED |
| Hybrid | SUPPORTED |
| Job-driven | NOT_IMPLEMENTED / FAIL-FAST(缺公司名单时显式报错,不静默降级) |
| Incremental Execution | KNOWN LIMITATION(Persistence 已实现;增量执行引擎未实现) |
| Persistence | SUPPORTED |
| V1 判据 / 提取器 | SUPPORTED |
不得把 Job-driven / Incremental 表述为「已实现」。「历史已持久化」≠「增量执行引擎已实现」。
1.5 JobMatch(三值,无评分)
Include / Exclude / Uncertain —— 严禁评分 / 排名 / 推荐排序。判据唯一真源 = 参数卡(Card.match_title / city_ok / stopped / year_uncertain);Skill 侧只补参数卡不覆盖的硬条件(实习偏好 / Open-State / 届次确认度)。Keyword Hit ≠ Student Match。
1.6 Completion / Failure
- Search Completion 基于 Search Scope;budget 用尽 =
PARTIAL,不是「无岗位」。 - Failure State 四值:
SUCCESS/PARTIAL/BLOCKED/FAILED。 - 铁律八机器化:任何否定结论必须有正面证据(详见 §2、§8.2)。
1.7 City-first 报告
结构为 Event → ⭐管培生 → 正式校招 → 实习,段内 Company → Job。生产 HTML 日报结构的唯一权威 = references/30-校招日报规格书.md;references/report-format.md 只贡献 City-first / 学生标签契约,不构成第二真源;references/22 只补渲染细则。
1.8 历史数据保护(append-only)
状态变化(如 open → closed)记录为新事件,不抹掉旧值;旧 Job 只标 superseded,不物理删除。一次性 Keyword Expansion 不写回 Student Profile。
1.9 指令层补充条款(2026-09-28 自 V2 2.0.0 并入)
本小节承接已归档的
campus-search-daily-v2(纯指令层 · 2.0.0)中尚未被 2.1.0 吸收的规范条款。已由代码强制或已在本文件他处覆盖的部分(措辞禁令、Open-State、Dedup 实现、City-first 结构、
参数卡唯一规则真源)不重复收录,避免产生第二真源。
1.9.1 请求优先级阶梯(P1–P5)
P1 当前用户请求 P2 Student Profile P3 Company Pool / 历史资产
P4 默认规则 P5 推测P5 不得变成硬条件。 当前请求不得偷偷修改 Profile:用户说「这次也帮 A 看实习」只改本次Search Request(internship=allowed);只有用户明确说「以后也接受实习」才更新 Profile。
1.9.2 Company Pool 生命周期与 Company Discovery 边界
Candidate → Watch → Target → Active Search → No Current Opening → ExcludedNo Current Opening≠ 不存在岗位,只是当前检查结果。- 用户明确给出企业时只搜这些,不得擅自扩展;仅当用户表达「再找一些类似企业 / 扩大范围」
才允许 Company Discovery。
- 开放式行业搜索(无公司名单)建立 Industry Scope,每行业覆盖约 10 家是 **coverage target,
不是 top-10 ranking;细分行业只有 6 家就搜 6 家,不得为凑数加入不相关企业**。
- Job-driven 缺公司名单时显式报错,不静默降级(与
v2_pipeline的 SystemExit 行为一致)。
1.9.3 Freshness(时效)
≤9 个月 → 正常
>9 个月 + 近期更新/刷新/重发 → 保留,继续验证
>9 个月 + 无近期证据 → freshness-risk
无法确认当前有效 → 不进入当前 active report
明确关闭 → closed字段:first_published_at / last_updated_at / last_refreshed_at / published_at_precision /published_at_source。不得因超过 9 个月直接删除 Job;绝不能覆盖 first_published_at 伪造「最新」。
1.9.4 Dedup 优先级(与 job_state.dedup() 一致)
1 Job/Requisition/Position/Posting ID 2 Official unique ID 3 Canonical URL
4 Company + Location + Batch 5 Semantic comparison禁止 title alone 作为去重依据。
1.9.5 关键词字典与临时扩展
保留来源性质字段 original / synonym / auto_english / market_title,便于回溯「某词从哪一步扩出来的」。一次性 Keyword Expansion 不得写回 Student Profile 或全局词表;只有用户明确说「以后也按这个搜」才更新。
1.9.6 指令层执行自检(每次执行按序)
[ ] 1 解析请求 → Search Request(含 Temporary Overrides,未擅改 Profile)
[ ] 2 确定 Search Mode(Company-driven / Job-driven / Hybrid / Incremental)
[ ] 3 构造 Search Scope(多学生取并集,一次搜索分别匹配)
[ ] 4 关键词扩展(中 → 英 → 市场表达)
[ ] 5 调度 Core Discovery(多 Channel;Adapter 优先,Generic 兜底)
[ ] 6 Found 验证(具体岗位 URL + 介绍 + 要求)
[ ] 7 排除判定(EXCLUDED / RETAINED + 依据码,不猜)
[ ] 8 Dedup(按 1.9.4 优先级)
[ ] 9 JobMatch 每学生(Include/Exclude/Uncertain,无评分)
[ ] 10 增量:只处理 NEW / UPDATED / CLOSED 分支
[ ] 11 Completion / Failure 判定(SUCCESS/PARTIAL/BLOCKED/FAILED,且 ≠ No Job)
[ ] 12 Report(City-first;管培置顶;匹配标签在末尾)
[ ] 13 时效与历史(append-only,不覆盖 first_published_at)
[ ] 14 措辞自检(事实型,无夸大、无推断)注:上表是指令层自检;§9「扫描作业九步法」是单企业作业层流程。二者层级不同,并行不悖。
1.9.7 指令层 → engine 调度映射(按 2.1.0 实际结构校正;V2 原文指向「盘上 Core」已失效)
| 逻辑函数 | 2.1.0 实际落点 |
|---|---|
discover_company_channels() | engine/adapter_hub.probe_family() + engine/orchestrator.discover_channels() |
identify_ats() | scripts/ats_registry.detect() + engine/scan_all.classify() |
run_adapter() | engine/adapter_hub.run() |
run_generic_discovery() | engine/generic_discovery.discover()(L1–L5) |
validate_deep_link() | engine/verify_links.js(Playwright 事实采集) |
persist_dlv_verification()(post-scan,C-01) | engine/dlv_verify.py(唯一 canonical 生产 DLV 阶段) |
derive_exclusion() | engine/job_state.derive_exclusion() |
dedup_jobs() | engine/job_state.dedup() |
persist_job_pool() | engine/orchestrator.update_pool() |
jobmatch(student, job) | engine/v2_pipeline.jobmatch()(判据唯一真源 = 参数卡) |
build_report() | engine/v2_pipeline.build_report()(City-first) |
调用纪律:Skill 不修改 Core 判定规则(发现缺陷记录并转交,不在 Skill 里打补丁);Core 的失败态SUCCESS/PARTIAL/BLOCKED/FAILED 原样传递,不美化改写;Core 返回的 Found / Open /Source Observations 直接使用,不重算。生产入口固定 launcher.py。
1.10 Runtime Mutation 纪律(RUN 阶段治理)
性质:本条是 治理纪律(Governance Rule),不是新的运行时 Guard,也不替代任何代码级护栏。
国际版已存在
engine/adapter_hub.run_controlled与 CH-10 / CH-11 代码级护栏(见 §1.10.3);本条 MD 不虚构这些护栏已覆盖全部 mutation surface。
为什么需要本条:Skill 包在生产 RUN 中会被反复执行、反复改 Workspace、反复迭代。为防止「发现问题 → 自动改代码 → 继续运行」导致的不可控变异,明确 RUN 阶段的读写边界与审批闸门。
1.10.1 RUN 阶段允许
下列行为在 RUN 阶段允许,无需额外授权:
- 读取 Skill(本文件 /
references//scripts//engine/); - 分析 / 阅读代码(只读理解);
- 运行诊断(
selfcheck/--self-test/qc_gate等); - 运行测试(含离线 self-test);
- 修改 Workspace(台账 / 参数卡 /
_scan// 报告 HTML /_scan/semantic/等,经--workspace注入); - 生成报告;
- 修改 Markdown(含本 Skill 的治理文档,见 §1.10.4 审批边界)。
1.10.2 受保护文件(mutation surface)
一旦发现需要修改以下任何影响 Skill 执行行为的文件,必须进入审批闸门:
Python · JSON · YAML / YML · TOML · 配置 · extractor · matcher · registry · launcher ·
以及其它影响 Skill 执行行为的文件。
审批闸门(强制):
发现需要修改 → 停止 → 说明问题(现象 + 根因 + 影响面)
→ 提出修改方案(改哪个文件 / 改什么 / 为何)
→ 等待明确授权禁止:发现问题 → 自动改代码 → 继续运行。
明确边界:「继续工作」 ≠ 「授权修改代码」。主理人说「继续」「接着做」「先扫下一家」等,均不构成对代码 / 配置修改的授权;任何 py / json / yaml / 配置改动,必须单独、显式授权。
1.10.3 既有代码级护栏(CH-10 / CH-11,非本次新增)
国际版 engine/adapter_hub.py 已落地 CH-10 / CH-11(合并于 2.1.0,2026-09-28):
- CH-10:
rg_runner.py(Runtime Guard Controlled Runner,位于 Workspace 根,可选组件)——
统一接管 JS Adapter(Playwright 注入脚本)的执行生命周期 / 退出码 / 清理 / 回显,业务 stdout 原样透传。
- CH-11:
adapter_hub._run_js以runner.run_controlled(...)取代裸subprocess.run([NODE, BROWSER_RUN]);
无裸 Driver 兜底路径——Runner 不可用时返回 RUNNER_UNAVAILABLE,由调用方判为硬失败,绝不回退到无监督执行。
已覆盖的 mutation surface:JS Adapter(浏览器 / Driver)执行入口(browser_run.js 经 NODE 启动)。
未被 CH-10/CH-11 覆盖(须由本治理纪律兜底,而非假设已受保护):
scripts/_mkbaseline.py向正式 Skill 包references/_baseline_*.json的包内写入(治理风险见references/91V13);engine/orchestrator.verify_links.js、自检与冻结脚本等仍走裸subprocess(非浏览器 Driver,超出 CH-11 范围);- 所有 .py / .json / 配置 / extractor / matcher / registry / launcher 的内容修改本身,CH-10/CH-11 不提供审批闸门。
结论:CH-10/CH-11 是执行层护栏,本 §1.10 是治理层纪律;二者互补,互不替代,亦不可互相冒充。
1.10.4 Markdown 与代码 / 配置的审批边界
- Markdown(含本文件、
references/27补充条款、references/91台账):可经治理流程直接修订
(本次重建即此类),但 Markdown 的修改不自动授权任何代码 / 配置改动。
- 代码 / 配置(.py / .json / .yaml / .toml / 配置 / extractor / matcher / registry / launcher):
任何修改必须走 §1.10.2 审批闸门,单独显式授权。
- 本次(2026-09-28)重建仅修改 Markdown,代码 / 配置 mtime 不变,实施状态 = NOT AUTHORIZED。
2. 宪法:两条总铁则 + 八铁律
⚠️ 宪法级 · 动手前必读权威本
references/27-宪法全本-八铁律.md。违反任一条 = 本期作废重做。
另见 §1.10「Runtime Mutation 纪律」—— 属治理补充条款 / 治理纪律,不新增铁律、不与八铁律并列。
两条总铁则(凌驾一切):
- 宁可空报,绝不假报。「本期扫 X 家,0 新岗」是合格报告;没岗位就是没岗位。
- 不过闸,不发报。QC 任一不过,本期不发(或剔除问题项复检)。
八铁律(全文见 references/27):
| # | 铁律 | 一句话 |
|---|---|---|
| ① | 无证据 = 没扫 | evidence 空/缺 → M_TO_SEARCH,不得进十三态 |
| ② | 扫前强制对账 | N = M + X,差异当场点名 |
| ③ | 完成声明必附 | M/N/X + 逐家原因,缺对账 = 假报 |
| ④ | 重扫禁复制旧结论 | QC1 仅日期/页脚差异 = 未重扫 = 不发 |
| ⑤ | 台账 URL 扫前实测 | 空/错则重发现并写回(用列名不用列字母) |
| ⑥ | 限速 | 并发由通道配额定;429 根因①配额②风控不得混判 |
| ⑦ | 穷尽方法 | 入口三级法①~③ + 收口态、深链方法 1~12 全试才可停 |
| ⑧ | 否定须正面证据 | 门槛不对称:判否定要正面证据,判未知只需证据缺失 |
⑧速查:确定否定 = D_NO_MATCH / J_STALE_ONLY / K_NOT_OPEN / 报告出现「无岗位」。正面证据 = 绕过池过滤的原始条目数 > 0,或 API 结构化空(Count:0 / positionList:[]),或页面显式空态(明确「暂无职位」且分页器共 0 条)。不够格:页面「看起来没东西」、渲染出壳、超时、run-code 无结果、错误信息为空串。
QC11 是铁律八的机器化实现(见 §8.2)—— 铁律八此前靠人守,现在靠闸守。
3. 深链发现主链路(本技能核心)
目标:
公司名 → 官方招聘入口 → ATS/自研系统 → 职位数据源 → Job Record → Job Detail URL
企业台账(公司名 + 台账 URL)
│
▼
┌──────────────────────────┐
│ ① verify_entries.py │ 全量·批量·便宜(1 请求/家)
│ 台账 URL 活着吗/有板吗 │
└────────────┬─────────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
OK_WITH_JOBS OK_NO_JOBS DEAD
(门后有板) (有门没板)★ (仅 404/410)
│ │ │
│ ▼ ▼
│ ┌────────────────────────┐ A_EXCLUDED
│ │ ② discover_entry.py │ 判死
│ │ 三级法靶向诊断 │
│ │ ①导航 ②子路由 ③bundle │
│ └───────────┬────────────┘
│ │
│ ▼
│ entry_discovery.json
│ → next_action 候选
│ │
│ ▼
│ ★ 人工复核 → 入册(ats_registry.json / http_sites.json / SPA_SITES)
│ │
└──────────────────┴──────────────┐
▼
┌──────────────────────────────┐
│ ③ ats_registry.detect() │
│ 判族(识别≠支持) │
└──────────────┬───────────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
supported=true supported=false 未识别
专用 extractor 不翻案(留痕) generic
│ │ │
└────────────────────┴────────────────────┘
▼
Job Records(17 字段契约)
▼
┌──────────────────────────────┐
│ ④ 三元组判据(§8.1) │
│ job_id + job_title + URL │
└──────────────┬───────────────┘
▼
⑤ 规则初筛 → 双池打标 → 十三态
▼
┌──────────────────────────────┐
│ ⑥ LLM 语义判断(§12) │
│ 只判「规则初筛后的候选」 │
│ 结论不入十三态、不覆盖规则 │
│ 首轮上限 300,达限不判死 │
└──────────────┬───────────────┘
▼
QC0–QC11 出厂闸门四条不可动摇的顺序:
- 先找招聘入口,再找岗位(不要一上来就要求 AI 找具体岗位)
- 先识别 ATS,再决定怎么采集(不要拿到 URL 就让 LLM 读网页)
- API > JSON > SSR HTML > DOM > 搜索引擎摘要
- 发现、提取、筛选、验证四阶段分离
LLM 段的顺序铁则:链路永远是 程序确定性采集 → 规则初筛 → LLM 语义判断。
LLM 只在规则初筛之后、只判候选语义;禁止前移到采集/发现/探活段(详见
references/32)。
4. ATS 注册表与指纹(识别 ≠ 支持)
权威数据在
scripts/ats_registry.json,本文只讲语义。
为什么必须有注册表:改造前「家族→提取器」映射是硬编码 if-else 且在包外 scan_all.py→ 换一块项目盘就丢一次知识,且无法被 qc_gate.py / verify_entries.py / 测试三方共享。
4.1 三值语义
| 判定 | 条件 | 动作 |
|---|---|---|
| 未识别 | match_hosts 与 match_patterns 均未命中 | family = "generic",走 _ex_generic.js 三级提取 |
| 识别 + 支持 | 命中且 supported: true | 翻案:family = <家族>,走对应 extractor |
| 识别 + 不支持 | 命中但 supported: false | 不翻案:family 保持 "generic",落并列字段 ats_recognized + ats_supported=false |
铁律约束:ats_supported = false 时 不得落任何确定态(铁律八)。「识别成功但支持不了」从静默退回 generic 变成显式带证据的记录。
关键设计:
family_of()未命中返回""而非"generic"——
"generic"是「分类默认值」,与「未识别」语义不同,混淆两者正是旧实现静默退回的成因。
4.2 指纹表(T0/T1)
指纹不另立文件,写在注册表同文件的 families[].match_patterns / fingerprint。理由:指纹与家族是一对多,拆两文件必然产生「注册表说 beisen、指纹表漏 zhiye 域」的漂移(坑 58)。
同名不同义警告:本节「指纹」= 平台识别;
references/26的 T0–T3 = 采集梯级。两者禁止混用(
references/90坑 79 已实证踩坑)。
4.3 调用契约
fam = ats_registry.family_of(host) # 未命中返回 ""(★不返回 "generic")
det = ats_registry.detect(url, body) # {"family","supported","confidence","hit",...}
if det["supported"]:
ex = ats_registry.extractor_for(det["family"]) # {"path","kind","method_label"}
else:
rec["ats_recognized"] = det["family"] # 并列字段,留痕不翻案
rec["ats_supported"] = False纪律:detect() 纯判定、不发请求 —— 这是保证纯标准库、单进程铁律、请求预算三条都不被破坏的关键。
python ats_registry.py --validate # 自检:extractor 在盘 / host 不冲突 / family 名合法
python ats_registry.py --list # 列出全部家族(✓=支持 ·=仅登记)
python ats_registry.py --detect https://boards.greenhouse.io/acme5. 采集引擎(四级梯子 + 反爬分级)
唯一权威本:
references/26-采集引擎细则.md(T0–T3 / 执行器契约 / L1~L4 全文)。
总原则:能用 API 拿明文 JSON,就绝不解析 DOM。
| 梯级 | 通道 | 成本 | 典型失效 |
|---|---|---|---|
| T0 API 直调 | 已知端点模板,响应为 JSON | 极低 | 401/403、端点 404、签名缺失 |
| T1 浏览器监听截 API | 端点未知但页面确实在拉数据 | 中 | 监听不到 XHR(纯 SSR) |
| T2 渲染 DOM 挖链 | 页面 SSR 或挂载后 DOM 有 <a href> | 中高 | SPA 卡片非 <a>、DOM 无 ID |
| T3 服务端渲染兜底 | 本地浏览器通道不可用 | 低(信息量少) | 拿不到交互层 |
执行器返回契约(失败必须可程序判定):必须返回 (code, data),code 固定:
| code | 含义 | 上层固定动作 |
|---|---|---|
0 | 成功且有数据 | 正常落盘 |
2 | 依赖缺失 | 立即中止本轮,不降级,上报环境问题 |
3 | 抓取失败 | 降级到下一梯级 |
4 | 登录墙(L3) | 落 F_AUTH,跳过该家、记账、下期重试 |
5 | 硬挑战(L2) | 立即停手,落 G_BLOCKED(明确≠没岗),切人工通道 |
6 | 超时 | 进补扫队列(不算失败降级) |
纪律:判「该不该降级」只看 code,禁止字符串匹配(if "ECONNREFUSED" in out 会静默走错分支)。2 与 3 必须分开;4/5/6 三分也必须分开(处置完全不同)。
反爬四级响应(只降级,不绕过):L1 软限流(退避 30s→300s)/ L2 硬挑战(立即停手,禁识别破解)/L3 登录墙(无凭据标 F_AUTH)/ L4 环境限制(换通道,一次只起一个)。每次降级把「信号原文 + 时间 + 采取动作」写进该家 evidence。
6. 入口发现三级法(找大门)
唯一权威框架:
references/16-入口发现.md。执行本节前必须先读。
目标:把「官网门户」映射成「真实职位板」;找不到时按尝试层级诚实下结论,禁止「漏抓后长得像成功」。
三级顺序不可颠倒:
| 级 | 做法 | 机器实现 |
|---|---|---|
| ① 页面导航链接 | 枚举 a[href],逐个 goto 看岗位 XHR(最权威) | discover_entry.level1_nav() |
| ② 合成子路由 | SPA 导航是 javascript:void(0) 时,按段位合成候选逐个试 | discover_entry.level2_synthesize() |
| ③ bundle 挖接口 | 连路由都点不出时,从 JS bundle 正则挖 API 路径再直试 | discover_entry.level3_bundles() |
| (收口态) | 邮箱/公众号投递型 = 「没有门」而非「没找到」 | 兜底收口、不计入尝试层级 |
「门户页假提取」识别(前置体检) —— 命中任一 → 不得判 C_MATCHED/D_NO_MATCH,转入口重发现:
| 信号 | 判读 |
|---|---|
| 条目大量含「公告 / FAQ / 招聘动态 / 通知 / 职位类别 / 筛选 / 清除」 | 门户页假提取 |
| href 指向列表页自身或全站首页,无单岗 ID | 门户页假提取 |
text 全为导航词 | 门户页假提取 |
| 条目数远小于该站公开的岗位总数 | 漏抓 |
正面口径:落盘条目里带单岗 ID 深链的比例才是健康指标(实测小米修复后 776/776 全带深链)。
6.1 机器实现(scripts/discover_entry.py)
python discover_entry.py --url https://join.qq.com # 完整三级诊断
python discover_entry.py --url https://x.com --out entry_discovery.json
python discover_entry.py --url https://x.com --dry-run # 只列候选不发请求
python discover_entry.py --self-test| 级 | 实现 | 约束下的取舍 |
|---|---|---|
| ① 导航链接 | html.parser 收集 <a href> → 逐个 urlopen → 复用 verify_entries.classify_ok() | 复用已实测的强弱词判据(STRONG_THRESHOLD=2),不重造 |
| ② 合成子路由 | references/16 候选模板常量化(16 条 + /{首段}/... 变体) | 命中即停;--dry-run 只打印候选 |
| ③ bundle 挖接口 | 正则抓同域 <script src>(限 2MB/个、限 8 个)→ 正则挖 /api/... → 裸探(405 转 POST) | 不做 JS AST 解析(无 pip);正则足够(实测腾讯即靠正则挖出 searchPosition) |
另附数据岛识别:__NEXT_DATA__ / __INITIAL_DATA__ / phApp.ddo(深链的另一常见来源)。
6.2 与 verify_entries.py 的分工(防重叠)
| 脚本 | 时机 | 职责 | 产出 |
|---|---|---|---|
verify_entries.py | 全量·批量·便宜(1 请求/家) | 台账 URL 活着吗 / 有板吗 | 入口探活分类归档 |
discover_entry.py | 单家·昂贵·靶向(~40 请求/家) | 真职位板在哪 / 接口在哪 | entry_discovery.json + 注册表候选 |
请求预算:单家上限由 --max-requests 控制(默认 40);--dry-run 兜底;并发硬编码为 1(串行),守单进程铁律。
6.3 联动闭环
verify_entries.py 判 OK_NO_JOBS(有门没板)
│ ← 固定处置动作(不得直接判 D_NO_MATCH)
▼
discover_entry.py --url <该家门户URL>
▼
entry_discovery.json → next_action.kind ∈ {http_sites, spa_sites, ats_registry}
▼
★ 人工复核 → 入册 → 下期该家自动走专用提取器(不再退 generic)纪律:
OK_NO_JOBS不得直接判D_NO_MATCH(references/16明文)。
next_action产物必须人工复核后入册 ——references/16铁律「禁止拼造 URL」。
判死六模式(启动三级法前先核对入口真的「死」):Chrome 无法访问 / size<4000 空壳 / size≈200 假壳 / 请稍候 JS 盾 / cookie 墙 / SPA 全路由同壳。
7.0 深链攻坚前置闸(Prior-Art 检索 · 治本项)
为什么有这一节:华为 2026-09-23 实测证明——失败根因不是缺配方,而是执行时没有强制检索既有知识。
references/17第 297–307 行早已登记完整华为配方(连网关租户别名头x-jalor-tenantAlias: hcm都在,并明写「缺它必空返回」),但从未被读取 → 同一坑重复踩。
缺口是「检索与强制」,不是「配方不足」。
触发条件(八项,命中任一即必须先检索)
| # | 条件 |
|---|---|
| ① | L_METHOD_FAIL |
| ② | E_EXTRACT_FAIL |
| ③ | ATS 已识别但职位抽取失败 |
| ④ | ATS/API 已识别但返回 0 jobs |
| ⑤ | 已发现职位列表页但无法生成 detail URL |
| ⑥ | 已发现 SPA 但尚未完成运行时职位数据发现 |
| ⑦ | 已获得职位 ID / 主键但无法确认 detail URL 语义 |
| ⑧ | 已经尝试过一种方法失败、准备切换另一种技术方法 |
检索顺序(至少走完)
references/17 家族速查表 → 对应 ATS / 技术家族文档 → 相关历史实验 / 已验证案例若项目现有索引机制能更准确定位,优先使用现有索引机制。
强制留痕
成功检索后,在该家结果中记录:
PRIOR_ART_CHECKED
prior_art_refs: ["references/17-深链捕获配方.md", "<对应家族文档>", ...](methods_tried 里含 PRIOR_ART_CHECKED 亦可,三者任一即算留痕。)
未执行的后果
已满足触发条件却未执行 prior-art check:
该家本轮结论不得进入十三态正式结论。
可保留实验记录,但必须标记为流程不合规 / 待补验。
机器落点与首期口径
- 判定函数:
scripts/_evidence_defs.py的prior_art_required()/prior_art_evidenced()/check_prior_art() - 首期接
qc_gate.py为 WARN-only(沿用 QC11 首轮先例)——不新增 QC 编号、不新增 BLOCK、不改 QC11。
⚠️ 重要限制(防误伤正常扫描)
本闸不是「每家公司、每次普通扫描都必须先读 references/17」。正常扫描、正常 API 抽取、正常 Browser fallback 不需要无条件执行。它只针对:已经进入攻坚、失败、异常、无法闭环,并准备继续探索的任务。
7. 深链捕获(找门牌,配方 1~12)
唯一权威本:
references/17-深链捕获配方.md(家族速查表、配方 A/B/B-2/五/五-B/六、J-1~J-4、战果登记)。执行本节前必须先读。
升级逻辑:按序尝试,前一个失败才用后一个,全败则标 L3_UNAVAILABLE 进④区。
| 方法 | 内容 | 对应梯级 |
|---|---|---|
| 1 | ATS 速查表直测(家族见 scripts/ats_registry.json,命中即走) | T0 |
| 2 | 站内搜索(搜岗位名,跨通道有效) | — |
| 3 | 列表翻页穷尽拾取 | T2 |
| 4 | 筛选器配方(字节/腾讯量大门户) | T2 |
| 5 | 导航穿透(官网无招聘区→逐层点) | T2 |
| 6 | 首页空壳路由枚举(轻量静态) | T2 |
| 7 | JS 包反编译 + API 直调(重量静态) | T0 |
| 8 | 真实浏览器渲染 + XHR 拦截(终极兜底,贵慢非确定) | T1/T3 |
| 9 | HTTP 直取(跳过浏览器,规格 extractors/http_sites.json) | T0 |
| 10 | 自研 SPA 捕获-重放(规格 _ex_spa.js 的 SPA_SITES) | T1 |
| 11 | 官方公开 API 纯 HTTP 直取(51job coapi / Avature / Workday CXS / Moka) | T0 |
| 12 | Phenom 数据岛 phApp.ddo 纯 HTTP 直取(翻页 &from=) | T0 |
方法 8 一句话定位:方法 7 与 WebFetch 服务端渲染都够不到时,用真实浏览器渲染 + XHR 拦截/离线挖 DOM href 拿深链。严禁替代日常量产扫描(贵、慢、非确定)。详见 references/14-SPA点击链逆向.md。
家族攻略索引:references/01(Phenom) 03(Oracle ORC) 04(Moka) 05(Workday) 06(CEC)07(北森) 08(飞书) 09(大易) 11(华润) 12(仟寻) 23(51job) 29(Radancy);国际端点形态见 references/24-国际ATS端点表.md;辅助工具 references/10-playwright-cli.md。
7.5 六阶段坐标(A~F)与 DL 分级
唯一总纲:
references/33-岗位深链自动发现机制.md(执行深链攻坚前必须先读)。本节只给坐标;配方本体仍以
references/17为唯一权威,入口方法仍以references/16为唯一权威。
references/33 ← 总纲:应该怎么发现 / 什么时候验证 / 如何分级
↓
references/16 ← 入口发现三级法(门在哪)
↓
references/17 ← 深链捕获配方 1~12 + 家族速查表(门牌怎么取)| Stage | 名称 | 既有资产 |
|---|---|---|
| A | 静态挖掘(路由字面量 / 详情页配置 / ID 型键名) | references/16 §一① / discover_entry.level1_nav() |
| B | JS bundle 反向(路由树 + API 端点) | references/17 配方五 / 配方五-B |
| C | 运行时网络捕获(XHR/fetch) | references/17 配方六 / references/14 |
| D | 搜索引擎反查 | 新增(references/33) |
| E | 第三方页面反查(只用于反查官方域) | 新增(边界见 references/33 §一) |
| F | 旧系统发现(legacy 通道) | 新增(如华为 reccampportal 型) |
四条禁令(违反即该家结论不成立):① 禁盲扫 ID ② 禁猜参数名 ③ 禁把列表页当详情页④ 禁看到 SPA 就直接判失败(必须续推 SPA → route → bundle → runtime network → XHR → job data → job ID → detail URL)。
硬规则 · 发现即转验证:一旦发现 detail route / job ID / API job record / detail URL template任意一种,必须立即转验证(生成候选 → DLV1~DLV5 → 记录事实 → 再决定是否继续探索),不得「不断探索、不断猜测、最后才验证」。
深链成熟度 DL0–DL5(并列字段,不参与十三态推导,见 §8.3):DL0 无证据 → DL1 仅列表/入口 → DL2 发现详情路由模板(参数语义/可访问性未确认)→DL3 发现职位 API 并取得记录 → DL4 可稳定批量取真实主键 → DL5 可批量生成 detail URL 并完成深链验证。
四条「≠」警示:
siteId ≠ jobId|数字 ≠ 职位主键|job_id ≠ detail URL|HTTP 200 ≠ 正确职位。
深链合格性 DLV1–DLV5:DLV1 可访问|DLV2 官方域|DLV3 岗位名匹配|DLV4 招聘身份|DLV5 非列表页。(命名避让:V1~V11 已被 references/91-待验台账.md 占用,故一律用 DLV 前缀。)
★ 唯一降维映射(dl_level + DLV → deep_link,唯一定义处 references/33 §四;代码调用 _evidence_defs.map_dl_to_deep_link(),禁止任何文件自行重写):
dl_level | deep_link |
|---|---|
DL0 / DL1 | L3_UNAVAILABLE |
DL2 / DL3 / DL4 | L2_RECOVERABLE |
DL5 且 DLV1–DLV5 全通过 | L1_HAS |
DL5 但 DLV 未全通过 | L2_RECOVERABLE |
DL5本身不是L1_HAS的充分条件。deep_link三值不扩展、不改名(references/30明文「不新增 L4」)。
探针:python scripts/discover_deeplink.py --url <入口URL> --stage AC --out dl_facts.json(只出事实;dl_level 由 _evidence_defs.derive_dl() 计算,脚本内不重定义判定逻辑)。
生产 DLV 接线(post-scan 阶段,C-01):_scan/*.json 的 detail_url_verified / dl_level / deep_link由唯一 canonical 阶段 engine/dlv_verify.py 回填(入口 launcher.py verify-dlv)。数据流:生产 detail_url(抽样 3/家,jobs[] 原序,确定性)→ verify_links.js 事实 → _evidence_defs.eval_dlv() → detail_url_verified(= DLV1 通过条数,抽样范围)→derive_dl() → map_dl_to_deep_link() → tmp + os.replace 原子回写。两条守卫:① B3(official_host_provenance=UNKNOWN → DLV2=None → L1_HAS=BLOCKED_BY_B3,非失败);② 传输失败(http_status=None → DLV 全 None,未知≠否定,禁读作 DLV1=False)。回写只动 deeplink_facts/detail_url_verified/dl_level/deep_link/verified_at,jobs/entry_url/matched_jobs/status 逐字不变。详见 references/33 §十一。
8. 成功判据:三元组 + 证据分级
8.1 Job URL 三元组判据(岗位级)
判据:「找到岗位」的最低标准 = job_id + job_title + job_url 三者齐备。
⚠️ 必要条件 ≠ 充分条件(2026-10-10 更正):三元组齐备只保证形式完整,
不保证正确。企业 ↔ 岗位 ↔ URL 不对应的错误岗位,即使三元组齐备也不算成功;
混入日报即判失败。正确性由 DLV 验证(
_evidence_defs.pyDLV1–DLV5)与去重/身份判定共同保证。
# scripts/validate_jobs.py
def check_triplets(rec):
has = [bool(str(rec.get(f) or "").strip()) for f in ("job_id","job_title","detail_url")]
n = sum(has)
rec["job_triplet"] = "T_FULL" if n == 3 else ("T_NONE" if n == 0 else "T_PARTIAL")
return rec["job_triplet"]以下全部不算「找到岗位」:找到公司招聘首页 / 找到校园招聘首页 / 搜索引擎出现公司职位 /页面出现「招聘职位」字样 / AI 推测存在某岗位。
纪律:三元组只 WARN 不 FAIL(--triplet-min 默认 0.6)—— 避免把合法的L3_UNAVAILABLE / G_BLOCKED 企业误判失败(铁律八)。
粒度警告:job_triplet / ev_level 是岗位级/证据级,十三态是企业级,不存在字段映射关系。禁止据它们去推断企业表「缺了几列」。
8.2 证据分级 EV0–EV5 与 QC11(企业级)
唯一真源:
scripts/_evidence_defs.py。与entry_status并列,不替换、不混用。
| 等级 | 含义 | 档位 |
|---|---|---|
EV0_NONE | 无任何证据(未扫 / 工具侧失败) | 无证据 |
EV1_URL | 仅入口 URL 可达(HTTP 200) | 弱 |
EV2_LIST | 列表页取得岗位条目,但无单岗 ID | 弱 |
EV3_TRIPLET | ≥1 条 job_id + job_title + job_url 三元组齐备 | 确定·最低门槛 |
EV4_TRIPLET_VERIFIED | 三元组齐备,且 detail_url 探活返回 200 | 确定·已验证 |
EV5_FULL | 全量三元组 + 自报 count 与实际条数对账通过(gap ≤ 5%) | 确定·全量 |
命名避让:既有 entry_status(E0_OK/E1_F_AUTH/E2_UNREACHABLE)是「可达性」维;EV0–EV5 是「证据强度」维。两者并列共存(避让 E0 命名冲突)。
铁律八的算术化 —— 封顶规则:
| 状态 | 封顶 |
|---|---|
M_TO_SEARCH(未取得证据) | EV1 |
F_AUTH(登录墙)/ G_BLOCKED(反爬)/ H_OFFLINE_ONLY(收口态) | EV1 |
entry_status = E1_F_AUTH / E2_UNREACHABLE | EV1 |
拿不到证据就不能判「没岗位」—— 封顶永不抬高等级,只会压低。
QC11 结论—证据匹配闸(铁律八的机器化实现):
| 检查 | 判据 | 动作 |
|---|---|---|
⑤区(K_NOT_OPEN/J_STALE_ONLY/D_NO_MATCH)任一家 | ev_level 必须 ≥ EV3 | 否则 BLOCK |
反爬/登录墙(F_AUTH/G_BLOCKED/H_OFFLINE_ONLY) | ev_level 封顶 EV1 | 超标即 BLOCK |
非终态(L_METHOD_FAIL/I_WRONG_ENTRY/M_TO_SEARCH) | 必须记录 methods_tried | 否则 BLOCK |
首轮纪律(--qc11-warn-only):首轮目标是验证规则、观察误报,不因规则问题直接阻断整批结果。
| 要求 | 实现 |
|---|---|
| QC11 正常执行并输出告警 | warn-only 下违规进 warns,不进 fails,退出码 0 |
| 告警必须落盘 | 强制写 <scan_dir 父目录>/qc11_warnings.json + .md(可用 --qc11-out 改) |
| 不因告警丢弃结果 | 落盘报告 results_retained=true / discarded=false;结果照常出厂 |
| 首轮后决定升级 | 落盘报告含「升级 BLOCK 候选」表:按规则桶统计命中数 + 逐条升级建议 |
落盘位置铁律:报告绝不写进
_scan/内 ——_load_scan_records用glob('*.json')扫整目录,写进去会被当成一家企业记录读回,污染 QC11/QC9 对账(坑 58)。默认落在
_scan的父目录。
# ★ 首轮上线务必先跑 warn-only:告警照出、结果照留、告警落盘
python qc_gate.py --scan-dir _scan --qc11 --qc11-warn-only --qc11-round 1
# 跑完后据 qc11_warnings.md 的「升级 BLOCK 候选」表,逐条确认无误报再转 BLOCK
python qc_gate.py --scan-dir _scan --qc11 --qc11-round 28.3 深链成熟度 dl_level(v1.2.0 新增 · 第 5 个并列字段)
唯一真源:
scripts/_evidence_defs.py(DL_LEVELS/derive_dl()/map_dl_to_deep_link())。方法论权威:
references/33-岗位深链自动发现机制.md§二 / §四。
定位:dl_level 描述深链发现/攻坚过程成熟度,是并列字段,与 job_triplet / ev_level / ats_recognized / ats_supported 并列 ——不参与十三态推导(十三态仍由 entry_status / job_presence / pool_match / deep_link 四层推导)。
与 deep_link 的关系(不可混淆):
dl_level → 深链发现/攻坚过程成熟度(细粒度诊断) → DL0 ~ DL5
deep_link → 现有交付口径 → L1_HAS / L2_RECOVERABLE / L3_UNAVAILABLE
deep_link仍然是正式报告、日报、补链队列及现有十三态体系所使用的交付口径唯一权威。
dl_level不得直接替代deep_link;两者之间只有一套降维映射(见 §7.5 表)。
取档规则:取「已达成能力」的最高档,不要求逐级通过(DL 是能力深度,不是步骤序号)。
落盘与校验:
| 项 | 规则 |
|---|---|
| 落盘 | 写入原始层 _scan/NNN_企业.json(dl_level + dlv 事实) |
| 校验 | validate_jobs.py:缺失放行(兼容历史数据)/ DL0–DL5 通过 / 其他值 FAIL |
| 报告 | 不进报告正文(deep_link 才是交付口径) |
9. 扫描作业(单企业九步法)
唯一权威本:
references/25-单企业流程细则.md(九步 + 十三态全表 +title_usable词表)。
| 步 | 动作 |
|---|---|
| 1 | 取入口 → ats_registry.detect() 判族 → 若「有门没板」自动转 discover_entry.py(§6.3);命中 §7.0 八项触发条件之一 → 先做 Prior-Art 检索并留痕 |
| 2 | ATS 分诊(supported=true 走专用 extractor;false 留痕不翻案) |
| 3 | 渲染(按梯级 T0→T3 升级) |
| 4 | 懒加载穷尽 |
| 5 | 双池同扫(YYZ/LQP) |
| 6 | 城市过滤(白名单 7 城) |
| 7 | 深链捕获(配方 1~12;六阶段坐标与 DL 分级见 §7.5 / references/33) |
| 8 | 落盘:先落判据字段组 → 再推导十三态 → 附证据;扫一家落一家,不攒批 |
| 9 | method 枚举(见 references/25) |
第 8 步落盘字段(含 5 个并列字段,均不参与十三态推导):
| 字段 | 取值 | 来源 |
|---|---|---|
job_triplet | T_FULL/T_PARTIAL/T_NONE | §8.1 |
ev_level | EV0_NONE…EV5_FULL | _evidence_defs.py |
dl_level | DL0…DL5 | _evidence_defs.derive_dl()(§8.3) |
ats_recognized | 家族名,或空 | ats_registry.detect() |
ats_supported | true/false | 注册表 |
两层落盘:
| 层 | 产物 | 说明 |
|---|---|---|
| 原始层(唯一事实源) | _scan/NNN_企业.json | 全字段;已终态即跳过 = 断点续跑;原子写(tmp+rename) |
| 视图层(可读/可审计) | 岗位筛选/结果_全场.csv、扫描记录.csv | 过滤后的十三态结果 |
十三态:A_EXCLUDED · B_ENTRY_PENDING · C_MATCHED · D_NO_MATCH · E_EXTRACT_FAIL · F_AUTH · G_BLOCKED · H_OFFLINE_ONLY · I_WRONG_ENTRY · J_STALE_ONLY · K_NOT_OPEN ·L_METHOD_FAIL · M_TO_SEARCH(仅 A_EXCLUDED 与 M_TO_SEARCH 不进日报)。唯一真源 scripts/_status_defs.py;由四层字段组推导,禁提取器写死 status。
⚠️ 迁移直译陷阱:旧
D_MATCHED→新C_MATCHED、旧C_NO_MATCH→新D_NO_MATCH(字母方向相反)。
纪律:scripts/validate_jobs.py 做落盘强 schema 校验(城市 [ 残留、分页完整性、词边界)。
10. QC 出厂闸门(QC0–QC10 + QC11)
全表权威:
references/30-校招日报规格书.md第七章。references/22第七节已降为指针(防坑 58)。
实装现状(2026-09-23 核对,文档与实装必须一致):
| 类别 | 闸门 |
|---|---|
qc_gate.py 自动实装(6 项) | QC0 / QC3 / QC5 / QC8 / QC9 / QC10 |
| 人工执行(5 项) | QC0b / QC1 / QC2 / QC4 / QC6 / QC7 |
| 本版新增 | QC11 结论—证据匹配闸(--qc11,首轮请加 --qc11-warn-only) |
过闸须逐项打印「查什么 → 看到什么 → 过/不过」,凭印象说「都过了」= 没过。
python qc_gate.py --report YYZ/YYZ校招报告_2026-09-22.html
python qc_gate.py --csv 岗位筛选/结果_全场.csv --expected-total 266 --scan-dir _scan
python qc_gate.py --scan-dir _scan --qc11 --qc11-warn-only
python qc_gate.py --scan-dir _scan --prior-art # §7.0 前置闸(WARN-only,永不 BLOCK)
--prior-art说明:v1.2.0 新增,对应 §7.0 深链攻坚前置闸。**首期 WARN-only、永不 BLOCK、不新增 QC 编号、不改 QC11**;命中八项触发条件却未留
PRIOR_ART_CHECKED证据的家会被告警点名。
退出码 0=可交付 / 1=有 BLOCK / 2=用法错误。交付声明必须附本脚本最后一次运行的完整输出。
11. 落盘与交付
- 报告结构:★管培生专区置顶 → ①线下 → ②岗位核心区(按城市)→ ③截止预警 →
④手动搜索区(按 status 分 7 组)→ ⑤已扫描无匹配(定序 K_NOT_OPEN→J_STALE_ONLY→D_NO_MATCH)
- 报告格式唯一权威:
references/30-校招日报规格书.md - 渲染细则:
references/22-报告渲染与出厂细则.md - 文件名:
YYZ/YYZ校招报告_YYYY-MM-DD.html(是「校招报告」不是「校招日报」—— QC 检查项) - 邮件四要素:见
references/30第九章 - 快照比对:与往期做差异比对(新增/消失岗位、状态迁移),差异须可解释(QC8)
12. LLM 语义判断(正式阶段)
唯一权威本:
references/32-LLM语义判断规格.md。机器实现:scripts/llm_semantic.py。定位:链路第三段 —— 程序确定性采集 → 规则初筛 → LLM 语义判断。只在规则初筛之后。
12.1 作用域(白名单唯一,黑名单硬拒)
LLM 只允许做「规则初筛后的候选岗位语义判断」:是否属 HR、HR 六大模块 / 三支柱、是否 HRBP、是否 HR 管培生、是否符合 2026/2027 届次、复杂 JD 语义判断。
| 禁止 LLM 参与(黑名单,13 项别名) | 程序职责方 |
|---|---|
| Career Entry Discovery / ATS Fingerprint | 三级法 + discover_entry.py / ats_registry.detect() |
| API / XHR / Bundle Discovery | discover_entry.level3_bundles() |
| 大规模岗位抓取 / 全量岗位遍历 | 各 extractor / 只喂规则初筛后的候选 |
| URL 存活判断 / 深链捕获 / 岗位提取 | verify_entries.py / 配方 1~12 / extractor |
代码硬闸(不是文档纪律):ALLOWED_TASK_KINDS = ("semantic_judgment",);assert_scope() 对黑名单抛 ScopeViolation,白名单外一律拒绝。
python scripts/llm_semantic.py scope --task-kind entry_discovery # 期望 DENY12.2 调用预算:首轮全局硬上限 300
llm_semantic_max_calls = 300(DEFAULT_MAX_CALLS)。达上限后四条硬约束:
| # | 约束 |
|---|---|
| ① | 不得静默截断 —— 溢出写 _scan/semantic/overflow.json,标 semantic_overflow: true |
| ② | 不得把未经过 LLM 的岗位判定为「不符合」 —— is_hr_related 保持 null(不是 false) |
| ③ | 必须落盘 LLM_LIMIT_REACHED / semantic_overflow(condition="LLM_LIMIT_REACHED") |
| ④ | 未完成判定的岗位保持候选/待审核 —— candidate_state = "待审核" |
12.3 两阶段执行
# ① 准备:收集规则初筛后的候选,按上限截断,产出 prompts.jsonl(+ overflow.json/manifest.json)
python scripts/llm_semantic.py prepare --scan-dir _scan --out _scan/semantic
# ② 回执校验:严格 schema,非法即 ERROR(不猜)
python scripts/llm_semantic.py validate --responses _scan/semantic/responses.jsonl
# ③ 合入:把语义字段写回 _scan/NNN_企业.json(并列字段,不入十三态)
python scripts/llm_semantic.py apply --semantic-dir _scan/semantic --scan-dir _scan12.4 非否定分类(宪法级)
「没有发现岗位」≠「没有岗位」。 达 LLM 上限、证据不足、访问失败等情况必须单独分类,不得转化为否定结论。机器守卫 guard_non_negative() 对「非否定条件 + 否定 status/措辞」报违规,prepare/apply 两处都调用。
13. 离线辅助(不进自动管道)
本节全部为人工触发、离线运行,不进扫描自动管道 —— 不破坏确定性、不影响可复现性。
13.1 词表挖掘(推荐优先)
python semantic_review.py --scan-dir _scan --out 词表补丁建议.md- 输入:
title_usable判「不可用」但pool_match = M2_NO_HIT的疑难条目 - 输出:「词表 patch 建议」(不是筛选结果)
- 流程:人工复核 → 写回
参数卡/或title_usable词表 → 下一期起生效
为什么这条是长期主路径:title_usable 词表就是规则化的语义判断,已实测把 19 家从「假无匹配」救回④区。把语义能力沉淀成规则,一次投入、长期复用,且不引入任何非确定性。原则是「LLM 用一次,规则用千次」。
13.2 深链攻坚诊断
遇到 L_METHOD_FAIL / I_WRONG_ENTRY 且两轮 10 分钟未破时,可用离线诊断:把 discover_entry.py 的产物(entry_discovery.json,含 bundle 片段与 API 候选)交给人工分析,产出注册表候选条目,人工复核后入册。
14. 未覆盖范围(转介清单)
- 报告运行频率:使用者决策,本 Skill 不规定、不预设分层调度
- 台账写回/企业踢出/补池/行业调整:主理人决策项
- 参数卡修改:主理人发起,走参数卡文件
- 线下招聘会场次采集:三源内不逐家,②区汇总展示
- 邮件发送时机与收件人变更:主理人指挥
- 通用采集引擎与
xiaozhao-job共用四级梯子 + L1~L4 词汇
15. 版本历史
当前版本以本文档 frontmatter 的
version:字段为唯一真源(现为2.2.37)。本节按版本倒序记录;
2.x为当前线;标注「历史」的条目为已归档存档,不代表当前版本。任何"当前版本"的判断,一律读 frontmatter,不得据本节尾部的历史条目推断。
2.2.37 = X1=B 落地:移除 Open-State 产品模型,改为排除判定(EXCLUDED / RETAINED)+ 依据码(2026-11-02):
事由:主理人 2026-11-01 裁定 X1=B —— 不建立 Open-State 产品模型;保留「排除证据识别与排除判断」能力。依据
产品契约/V0.3_产品能力契约.md§2.3 / §10 / §18;整改规格整改方案_20261101/04_open_state模型改造规格_20261101.md。实现:
job_state.derive_open_state→derive_exclusion(二元判定 +EXCLUSION_BASIS:E1–E3 / R_NO_EXCLUSION_EVIDENCE / R_UNDETERMINED / R_NOT_OBSERVED;★ P1 V0.3 §10.2.2:DEADLINE_EXPIRED/API_MISSING属执行层证据类型,不设 E4/E5、不得据此排除;open取值彻底消失;关闭证据匹配器保留为证据识别器);data_contract的OPEN_STATES→EXCLUSION_DECISIONS+EXCLUSION_BASIS,make_verdict硬约束EXCLUDED ⇒ E* ∧ evidence_refs 非空/RETAINED ⇒ R*(fail-loud);job_review删除EXTERNAL_OPEN_STATE/to_external_state/OPEN_STATE_PASS,stats.counts+stats.internal→stats.exclusion{excluded,retained,retained_undetermined};build_report剔除口径改exclusion_decision == "EXCLUDED";report_dataset透传新字段;新增engine/legacy_exclusion.py(旧产物open/closed/uncertain/IE→ 新判定,独立兼容路径,不回写、不泄漏)。验证:全量回归 74/74 OK(0 FAIL / 0 SKIP,1162.6s);新增 T14 兼容测试(
test_data_contract+8);§7.5 硬门 PASS —— 三批真实产物(_scan35,298 / fullrun 4,949 / diag 402)交付集合改造前后按dedup_key完全一致,open_state分布 35,298 IE / 418·4,475·56 / 50·352,closed三批合计 0;冻结_scan未被写入(mtime 2026-10-07)。未达成(如实登记):排除路径真实数据触发未取得(三批
closed=0)⇒ 排除能力实现状态记IMPLEMENTED_ONLY,不得记PRODUCTION_VALIDATED(spec 04 §10.2 独立事项)。
2.2.36 = 标题栏白话说明删除(规格书)+ ④手动搜索区企业名进日报(2026-10-30):
事由:主理人 2026-10-30 裁定 ——「标题栏白话说明从规格书删除,手动搜索区逐家明细,企业名需要进日报」。前者推翻旧规格书第 51 行标题栏白话说明条款;后者推翻旧规格书第 74 行「只报家数 + 一行去向说明」口径,改与 §6.3「组下列企业(企业名 + 附带线索)」对齐。
实现:
references/30-校招日报规格书.md第 51 行删除标题栏白话说明、第 72/74 行改为「按组列出企业名」;build_report.py的_manual_search_groups由「只报家数」改为「家数 + 企业名列表(组内按名称排序)」,④区说明文案同步改为「按组列出企业名与去向」;references/22-报告渲染与出厂细则.md、campus-search-daily_十三态速查表.md同步删除白话说明;架构设计基线_V0.4§26.5/§26.6、V0.4_执行清单_v4.5§4.2 同步「企业名进日报」。验证:
test_report_zones.pyC5 断言改为「④区列出企业名」;test_report_scandir.py25/25、test_delivery_admission.py16/16、test_event_p2_4.py22/22;真实 4 家诊断批次渲染实测④区企业名可见。
2.2.35 = 日报结构回退旧规格书六区(管培生专区恢复)+ 删除开放状态待确认区(2026-10-30):
事由:主理人裁定「旧规格书不许改。改架构基线和执行清单。」
references/30-校招日报规格书.md(定稿 v1.0 · 2026-09-20)为日报格式唯一权威;架构基线 V0.4 第26章、执行清单 v4.5 中与旧规格书冲突的「三板块」条款已同步改回六区。实现:
build_report.py恢复六区:★管培生专区(置顶、独家、不重复进核心区)→ ①线下招聘会区 → ②岗位核心区 → ③截止预警区 → ④手动搜索区(7 组 B/E/F/G/H/I/L)→ ⑤已扫描无匹配名单区(K→J→D);删除「开放状态待确认区」与「开放状态未确认」标记;板块编号改固定(空区省略不导致错位);新增_manual_search_groups/_no_match_groups。标题栏不加白话说明(主理人明确不需要)。验证:
test_report_zones.py重写全绿(六区结构、管培生专区、④七组、⑤ K→J→D、编号固定);test_report_scandir.py25/25、test_delivery_admission.py16/16、test_event_p2_4.py22/22;真实 266 家冻结_scan渲染实测板块顺序★ → ③ → ④ → ⑤(①/② 无数据省略,编号未错位)。
2.2.34 = P2-4 招聘活动 Event 接入生产链(发现 → 验证 → 准入 → 日报首位)(2026-10-29):
事由:《第二期 P2-4 招聘活动 Event 实施与验收》——将活动能力从 ABSENT 接入生产链,不改动已验收的 Coverage / 完成信号。
实现:新增
engine/event_discovery.py(通用特征识别 + 岗位记录排除 + 时间/取消归一化 + 身份去重 + 三字段验证 + 详情链接校验 + 三态结论 + 轻量 HTTP 来源抓取);scan_one落盘events/event_status/event_discovery(异常不得转成「无活动」);build_report将 Event 区置于首位并动态编号,无活动时整区省略。验证:
test_event_p2_422/22;真实端到端iso_ws_xd_event_20261029(信达,exit 0)NO_VALID_EVENT+ 日报无 Event 区、无占位泄漏,YYZ 3 / LQP 7;可回放正例 DELIVERED(2 准入 / 2 拒绝,Event 区首位)。真实平台有效活动样本未取得(归因 A)。
2.2.33 = 完成信号生产链断点修复(落点纠正 + T1/全失败不误判 + Discovery 消费机器信号)+ 真实运行 COMPLETE 证明(2026-10-29):
事由:《2.2.32 最终收尾执行指令》——验收发现 2.2.32 的机器信号从未被消费(写 meta 顶层、消费者读
browser_escalation);且 T1 命中即停 / 全 FAILED 会被误判为「策略集耗尽」;escalation_exhausted用粗粒度 ledger 会在 T3 预算耗尽时误判 True。修复:①
_browser_escalate将escalation_plan_complete/termination/ledger_counts/skipped/exec_verdicts写入browser_escalation(顶层留审计副本);② 判据收紧为termination ∈ {T2,T4}∧NOT_EXECUTED_INCOMPLETE=0∧ 无SKIPPED_BY_STOP_RULE∧ 非全 FAILED;③build_source_coverage有机器信号即以其为准(不再叠加EXHAUSTED文本,避免全失败误判);④derive_discovery_completion的escalation_exhausted优先消费机器信号(False ⇒ None,不判 C4)。验证:新增
engine/test_signal_chain_integration_2233.py11 场景(真实 Planner→to_rep→_browser_escalate→build_source_coverage→run_coverage全链,仅替换浏览器 I/O);真实运行iso_ws_xd_2232_20261029复用(run_completion=COMPLETE/terminal_result=SUCCESS/ YYZ 3 / LQP 7)。
2.2.32 = 信号落地与 Coverage 阻断闭环(Planner completion 回填 + escalation 完整性证据升级 + 探测页不污染 all_parsed + 新增闭环测试)(2026-10-29):
事由:《企业级 Coverage 根因修复与闭环任务》——修复「企业级 Coverage 无法可靠判断搜索是否完整」:来源级计数被升级覆盖的单一
scan_meta.total与含多来源/非岗位的raw_count做不可比比较(§1.7-A 禁止)。build_source_coverage来源级分别保存;run_coverage同源同范围对账 +_sc_complete门控(all_done=False⇒ 诚实 PARTIAL)。信达隔离运行:CR-1由EXECUTED_FAILED(83 vs 158) 修正为EXECUTED_OK(a_layer 91==91),sources_incomplete=["escalation"];YYZ 3 / LQP 7 无回归。
2.2.30 = 请求侧范围证据口径收紧 + Moka 正式链学生端交付实测 + Category 缺失交付安全闸与 Coverage 口径追溯(2026-10-28):
事由:《2.2.29 最后验收补缺任务》——三项补缺:①未知平台族请求侧范围证据的语义边界;②Moka 思特威正式链学生日报正向验收;③Beisen 分类与 Coverage 对账闭环 + Category 缺失交付安全。
任务一(请求侧范围证据):
_api_call_chain_basis的entry_tok由「_path_tenant_tokens ∪ _tenant_tokens」收紧为「仅_path_tenant_tokens」——_tenant_tokens含入口查询值(page=1/lang=zh/LocId=[…]),非租户标识,纳入会使「API 范围参数值==入口查询值」的无语义巧合进入候选。_api_namespace_reason/_req_scope_hit逻辑不变:参数名∈范围参数 ∧ 取值==入口 PATH token 两独立事实同时成立才计证据;非语义参数名即便值==token 一律 fail-closed。新增TestRequestScopeEvidenceSemantics6 项。任务二(Moka 正式链):
launcher.py scan --profiles YYZ,LQP(scan→verify-dlv→report)在隔离工作区一次跑通:raw=79 usable=78、DLV 78/78、DL5、count_reconciled=True;候选971aa5bf…「商务专员【27届校招】」入 LQP 日报(HTML 实测 UUID/标题/集团/详情链接),A1=PLATFORM_API_SCOPE/SCOPE_API_CALL_CHAIN、A3=真、DLV1=真、job_level_basis=identity_present_in_rendered_job_anchors。岗位级 A1 仅 29/78(有可追溯身份者),49 条无锚点身份 ⇒ A1 未成立(未把 30 锚点扩到 79)。任务三(Beisen Coverage):
grab_beisenadapter 级同范围对账成立(campus_by_label=91 == campus_declared=91,全量 1258/1258);运行级CR-1因「单通道岗位计数 vs 全候选计数(含非岗位噪声+escalation)」口径不可比,如实保留 FAILED(未改分母造假);71≠141 根因为 141=全部身份候选(94 JOB+47 非岗位),非岗位不存在。新增 Category 缺失交付安全闸:category_field_absent⇒campus_scope_unproven⇒count_reconciled=False且delivery_admission第四闸拒绝交付(保留候选不假零值)。信达正式链 YYZ 3 / LQP 7 真实 2027 届校招岗。实证:
test_platform_api_scope96→102、test_beisen_category6→8、test_delivery_admission+3;全量回归见验收报告。未达成(如实登记):其他未知平台族无真实正向样本(通用逻辑已测试、真实能力
INSUFFICIENT_EVIDENCE);无「Category 缺失」真实租户样本(安全闸为通用逻辑已测);运行级 CR-1 差异如实保留。
2.2.29 = 未知平台族不再凭「字符串巧合」自证归属 + Moka 不透明 job-list 的 org 范围归属 + Beisen 分类去硬编码与计数对账(2026-10-28):
事由:主理人《2.2.28 后续技术收口任务书》——三项遗留技术缺口须以代码/真实运行/测试/学生端证据收口:①未知平台族「凭什么成立」;②Moka(思特威)岗位级 A1;③
grab_beisen的Category硬编码与CR-1计数对账。任务A(未知平台族):
_api_namespace_reason的 token 分支由子串包含改为离散片段匹配(_url_discrete_parts/_token_hits_url,排除时间戳/分页参数巧合重叠);未知平台族仅「入口与 API 出现同串」不再成立(same_host_unknown_family_token_string_match_no_scope_evidence),须由请求侧范围证据(_req_scope_hit:平台命名参数orgId/tenantId/portalId/suiteKey…取值 == 入口 token)提供通用归属路径;已登记族按声明保持正例。观测面verify_links.js每条主帧 JSON 响应附req_params(白名单,不落凭证)。保留 2.2.28 未登记族 fail-closed。未引入企业名/特例/主机白名单。任务B(Moka 岗位级 A1):实测(思特威)主帧 11 个 JSON 响应全部带
orgId=smartsenstech1;jobs/v2返回密文 blob(records=0);页面渲染 30 条#/job/<uuid>锚点;grab_moka明文 79 条且native_id与锚点 uuid 同源。新增「不透明 job-list」路径①':主帧 ∧ 200 ∧ 请求侧 org 范围证据 ∧ 页面渲染 ≥1 岗位锚点,作为与「解析记录≥1」同等强度的独立事实(_chain_records_are_job_anchors区分解析记录是岗位池还是辅助端点);命名空间经req_scope成立;岗位级 ④ 在记录池不含身份时回退渲染锚点匹配。真实端到端produce_site_binding=established(PLATFORM_API_SCOPE/SCOPE_API_CALL_CHAIN/identity_present_in_rendered_job_anchors)。反证:混合 org / 无请求证据 / 无锚点 / 非主帧 / 非本页岗位 一律 fail-closed。任务C(Beisen 分类与 Coverage):
Data[]每条同带Category(标签)与CategoryId(码)⇒Category是租户字典。grab_beisen去Category:["2"]硬编码:不带 Category 取全量并按Count分页拉全 → 按记录自述标签筛校招(校园/校招/campus,排除 实习/intern)→ 从数据发现校招CategoryId→ 用发现码再查 Count 对账;category_field_absent防假零值。实测:信达 校招 91(标签 91 == 发现码 91,全量 1255/1255 complete)、复星 76(76==76,171/171);CR-1 COUNT_RECONCILE复算EXECUTED_OK(91==91),2.2.28 的「71≠141」消除。未通过「取所有分类」掩盖差异。实证:
test_platform_api_scope87→96(任务A 离散片段/请求侧证据正反例 + 任务B 不透明 job-list 正反例;2.2.28 旧正例「未登记族 token 复现即成立」按新规则改写);test_beisen_category新增 6(含「校招码=7 仍被发现」决定性反证、混合分类只取校招、缺 Category 不清空、250 条跨页收齐);全量回归见验收报告。未达成(如实登记):Moka
open_state/DLV 回喂仍属跨模块证据契约(2.2.28 已登记);Category 标签词表以「校园/校招/campus」为准,非常规纯英文标签的租户需按 PROPOSAL 补字典声明。
2.2.28 = 未登记平台族不再默认「企业自有域」+ hotjob 租户位置纠正为 path + 升级合并留痕落盘(2026-10-27):
事由:主理人《2.2.27 分层验收补缺 · 命名空间边界与信达最终日报》——2.2.27 有三处验收缺口(未登记平台族凭什么放行 / hotjob
origin是否符合真实租户机制 /path族只有单测没有生产样本),外加信达学生端交付链须在正式入口上端到端跑通。任务一A(未登记平台族):
_api_namespace_reason同 host 分支原有return ""(未登记 ⇒ 放行)——这是把「本系统不认识这台主机」当成「这台主机属于目标企业专属」。注册表是有限枚举,未知 ATS 同样是共享主机(多租户共用一个 host、租户在路径或参数)。改为same_host_family_unknown_ownership_unproven(host=…,registrable_domain=…)。判据只减不加:入口路径标识符型租户 token 复现在 API URL 仍成立(hr.xiaomi.com/campus/2027campus01↔…/api/2027campus01/…)。企业自有域的正解是登记族/租户位置(可追溯的域名归属证据),不是「没登记 ⇒ 默认自有」。未引入企业名 / 主机白名单 / 共享主机名单。任务一B(hotjob 租户位置):注册表
hotjob.tenant_scope由origin纠正为path。实测(先声药业,268 条 / 18 页):入口wecruit.hotjob.cn/SU61458d83bef57c54dcb4e43f/pb/school.html↔ APIwecruit.hotjob.cn/wecruit/positionInfo/listPosition/SU61458d83bef57c54dcb4e43f,租户标识是路径段,_ex_hotjob.js亦从路径取 tid;共享 host 承载多个 suite ⇒ 同 host 不能自证。原origin声明只在「入口恰好带SU…」时才因 token 命中而未暴露。新增负例锁:同 host 不同SU…⇒same_host_tenant_token_absent;API 不带SU…⇒ 不成立;入口无SU…⇒same_host_tenant_scope_path_token_absent;并用反证用例固定「若仍声明 origin,这两个负例都会被放行」。不新增分公司 /siteId前置。任务一C(
path族真实样本):思特威(Moka)单家隔离 E2Eiso_ws_moka_2228_20261027,入口app.mokahr.com/campus-recruitment/smartsenstech1/56088#/jobs;生产观测面 12 条主帧 JSON 响应(全部 200 /frame_main=true),承载记录的为…/api/outer/ats-apply/website/jobs/departments/flat(records=1)与…/privacy-policy/get(records=1),均不含租户 token ⇒same_host_tenant_token_absent⇒ A1 0/78。租户证据实际出现在…/api/extension-server/extension/list-by-org?orgId=smartsenstech1(查询参数、records=0、不进 chain)。结论:path族规则在真实样本上按设计生效;Moka 的 A1 缺口是观测面(页面 API 不带租户 token)而非规则缺陷,放宽为「页面级租户绑定」属证据标准变化 ⇒ 提交授权,本版不实施。任务二(信达学生端交付链):保留 2.2.27 的
merge_escalation_jobs(本轮无回归证据,未重写主体),补一个留痕缺陷:合并结果{policy,kept_a_layer,from_escalation}2.2.27 只写进meta,scan_one未拷进rec⇒ 产物里看不到合并事实;补rec["escalation_merge"]并加接线锁。正式链launcher.py scan(scan → verify-dlv → report)在信达官方入口一次跑通:jobs=94(A 层api_record86 + 升级追加 8)、A1∧A3 86/86、DLV 87/87 DLV1、dl_level=DL5、deep_linkL2_RECOVERABLE→L1_HAS、scope_match∧student_match10 ⇒ YYZ 入报 3 / LQP 入报 7(HTML 实测链接为真实campus/detail?jobAdId=<UUID>)。terminal_result=PARTIAL的原因如实登记为COUNT_RECONCILE(页面声明 71 ≠ 解析 141),不是 DLV 或 report 失败。实证:
test_platform_api_scope72→87(新增TestUnknownFamilyFailClosed8 项 +TestHotjobTenantLocation7 项)、test_campus_subroute_hop25(hotjob 声明断言纠正)、test_escalation_merge8→9(新增留痕落盘接线锁);真实配对翻转核查(21 个隔离工作区 / 122 对 + Moka 观测面 12 条)翻转 0;全量回归见验收报告。未达成(如实登记):① 信达
open_state仍 84 条INSUFFICIENT_EVIDENCE(step6.observation_complete=false,详情页开放状态未在 Step-6 内实测;DLV 的实测状态未回喂 Open-State——属跨模块证据契约,非本批可改);②grab_beisen的Category:["2"]仍是租户字典硬编码;③ Moka 页面级租户绑定(PROPOSAL,待授权)。
2.2.27 = 命名空间判定补齐「租户位置」维度(不再以「入口无 token」推定同租户)+ 升级链不再顶掉 A 层 API 身份池(2026-10-27):
事由:主理人任务书《命名空间判定与信达岗位身份关联 · 实施闭环任务书》——①同 Host 不得「不证自认」为同租户,且不得靠一刀切拒绝规避;②信达经真实官方入口后仍
no_api_record、岗位级 A1 不成立,须查清属五种真实情况中的哪一种并修可修断点。任务一(命名空间):新增
_platform_resolution(url) -> (family, tenant_scope),只读注册表族级tenant_scope(origin/path/site),零企业名、零主机白名单。同 host 分支按声明分流:origin(beisen/hotjob,租户在子域)与site(http/spa/links/generic,企业自有域)⇒ 同 host 即同租户;path(moka/51job,租户在路径)⇒ 路径 token 缺失即 fail-closed(same_host_tenant_scope_path_token_absent);已登记未声明 ⇒ fail-closed(same_host_tenant_scope_undeclared);未登记 ⇒ 企业自有域 ⇒ 成立。_path_tenant_tokens分两档:标识符型(含数字)恒收、纯字母 slug 仅在path族收且先过_CHANNEL_PATH_WORDS(social/campus/about/join-us不入 token)。修掉两个真实缺陷:2.2.26「无标识符 token ⇒ 直接放行」使共享主机族的纯字母租户退化为不证自认;_IDENT_TOKEN_RE强制含数字导致campus-recruitment/pwc类纯字母租户被漏判。条件④(身份键在池)保持独立 AND,不得替代范围证明(回归锁test_identity_hit_does_not_replace_scope_proof)。任务二(信达身份关联):根因(FACT)不是捕获缺陷,也不是缺字段,而是升级链整体替换——A 层
grab_beisen已从GetJobAdPageList响应本体取到 86 条岗位(native_id=响应Id、http_status 实测 200、十键api_record齐备),这是岗位级 A1 唯一可成立的身份池;升级链走 51job 搜索反查,身份是对方平台数字 id,与 A 层 API 池不同源 ⇒ 必然no_api_record。旧实现jobs = _j2(engine/scan_all.py)把 86 条身份池整体顶掉,换成 8~11 条 51job 岗位 ⇒ 全量 A1 不成立。修法:新增纯函数merge_escalation_jobs(a_jobs, esc_jobs)——A 层带api_record者全保留,升级结果按dedup_key/job_id去重后追加(留痕escalation_merge);A 层无api_record时保持旧行为。实证:
test_platform_api_scope60→72、test_campus_subroute_hop22→25、test_escalation_merge新增 8(含接线核验);真实配对翻转核查(只读,118 对,hotjob 81 / beisen 37)翻转 0;信达隔离 E2Eiso_ws_xd_ns27b_20261027:jobs=97、api_record86 条、SCOPE_API_CALL_CHAIN证据 86 条且job_level_basis=identity_present_in_platform_api_records、detail_present86/86、job_presence_in_scope=true、scope_match∧student_match10 条(2027 届真实校招岗 + 真实 detail URL);对照修复前iso_ws_xd_ns27_20261027:jobs=11、api_record 0、job_presence_in_scope=false。未达成(如实登记):
open_state中 76 条为INSUFFICIENT_EVIDENCE(详情页开放状态未逐个实测),仅 10 条走通到学生交付链;Category:["2"]仍是grab_beisen的硬编码取值(实测该租户["2"]=86 /["1"]=1148 /[]=1245,Category 是租户自定义字典,硬编码在换租户时可能取到非校招集合)——列为下一版 adapter 层前置,本版不声称已解。
2.2.26 = §L 类级泛化:平台族标准校招子路由 + 一跳频道语义排序,教会 skill 解决「纯 JS 裸 host 平台门户」(如 beisen/信达)这类企业的深链(2026-10-26):
事由:主理人定调「教会 campus skill 将来如何解决类似信达这种企业的深链,而非仅修信达一家」。2.2.25 把 beisen 全族误杀(
/social频道词被当租户 token)已修复,但信达端到端仍卡在「入口不链/campus/jobs(<a>=0、纯 JS 导航)」。本版在注册表ats_registry.json为平台型家族登记campus_subroutes(标准校招子路由),augment_scope_with_hops在页面无真实校招频道候选时合成并标注synthesized,同时加频道未漂移结构闸(合成目标须出现真实岗位锚点或 API 记录,否则不采信、fail-closed)。一跳候选改为按频道语义打分排序(校招 +2 / 社招 -3 / 中性 0),留痕hop_candidate_audit,不删除任何候选。类 A 裸 host 平台门户三层现状:①命名空间(
/social不再误杀,2.2.25)✅;②频道歧义(校招优先,2.2.26)✅;③标准子路由发现(/campus/jobs可被观测)✅;④页面→API 身份链接(纯 JS 页初始 HTML 无真实岗位卡片,适配器抓频道/城市噪声,api_record空)❌——属 adapter 层边界,已在验收报告如实登记为下一版前置,不以此声称类 A 全部 A1 可达。实证:
test_campus_subroute_hop新增 22 项全绿(裸门户命中合成候选 / 不覆盖真链接 / 社招页不越界 / 未注册家族不合成 / 结构闸拦截无岗目标 / 命名空间不匹配仍拦);test_platform_api_scope60/60(含信达innoventbio.zhiye.com/social↔ API 回归锁);test_site_scope全绿;信达隔离 E2Eiso_ws_xd_beisen3_20261026:合成/campus/jobs被观测(hop_synthesized observed=1、scope_hop_observed=2),a1_established=0因④未达(no_api_record8),如实登记,不虚报。测试:
test_platform_api_scope49→60 项(新增test_path_tokens_require_identifier_shape、test_beisen_channel_path_not_constrained、test_identifier_token_protection_retained,删除已消失代价的test_own_site_nav_tokens_do_not_break_attribution);test_campus_subroute_hop22 项。
2.2.25 = §L 任务四落地:同 host 命名空间不再等同同租户(fail-closed 收紧)(2026-10-26):
事由:2.2.24 把「同 host 命名空间比对不含租户 token」登记为 PROPOSAL(待授权)。主理人明确「技术侧自决、不上呈」⇒ 本版把收紧实施完毕(判据只增不减,属证据标准收紧而非放宽)。
① 判定面(
site_scope._api_namespace_reason新增 +_api_namespace_ok改为其投影):条件②由两类形态扩为三类——同 host ∧ 入口路径无租户 token ⇒ 成立(自有域名型,租户在子域,如fosunpharma.zhiye.com);同 host ∧ 入口路径 token 出现在 API URL ⇒ 成立(共享主机族租户在路径,如/SU61458…/↔/listPosition/SU61458…);同可注册域 ∧ token 相符 ⇒ 成立(Moka 型跨子域)。同 host 但入口 token 不在 API URL ⇒ 不成立(共享主机族不得凭「同 host」推定同租户)。② 留痕精确化:失败 basis 由
api_namespace_mismatch(api=…,entry=…)增补why=子原因(same_host_tenant_token_absent(entry_tokens=…)/cross_registrable_domain(…)/cross_subdomain_tenant_token_absent/empty_url/host_unparsable),阻断点可直接定位。③ 粒度不变:未新增分公司/
siteId要求,集团级结论仍由轴②(身份键在池)逐岗承担;_path_tenant_tokens只取路径段(查询值、含.的文件名段不入 token,避免LocId=[…]噪声误杀)。④ 已知代价(显式登记,测试锁定):自有域名入口路径含导航词(
about/join-us/open_positions类)而 API 走通用路径时,条件②会否证 —— 该类企业若仅靠路径③取 A1 将回落其它路径;实测未发生(见下)。实证(旧规则 vs 新规则,对已留痕真实响应逐对比对):11 个隔离工作区 / 92 个 (entry,api) 配对 ⇒ 翻转 1 个,且该响应
records=0(wecruit/common/mark/info辅助端点,本就不入chain)⇒ 功能面零影响;iso_ws_l_named(智元/传音/联影)6 配对 0 翻转。收紧后复跑隔离 E2E:见 §4 / 交付报告。测试:
test_platform_api_scope49 → 58 项(新增TestSameHostTenantTightening9 项:无 token 同 host 成立、token 相符成立、通用路径阻断、他租户阻断、端到端精确 basis、端到端正例、无 siteId 要求、_path_tenant_tokens只取路径、导航词已知代价锁);test_hotjob_api_record20/20 复跑。
2.2.24 = V0.4 §L 收尾:岗位级 A1 证据覆盖 + Hotjob A3 补齐(2026-10-26):
事由:主理人《§L 最后收尾》四项——①修复复星岗位级 A1 证据覆盖(首屏池 20 条 vs 发现层 74 条);②闭环信达官方第三方活动路径(不得用推测路径替换真实链接);③修复 Hotjob A3(不得推迟到 P2-1);④复核集团级范围证据 fail-closed 边界(只读)。
① 观测面补齐(
verify_links.js):scope 模式新增主帧分页交互——(a) 滚动增量加载(终止=连续两轮文档高度∧正文长度均不增长,SCROLL_MAX=8);(b) 显式分页控件「下一页」(候选按-nextclass → title/aria-label 排序,排除jump-*(Ant Design「向后 5 页」只移窗口不发请求,实证 18 页只翻到 10 页),进度信号=已捕获响应数,PAGE_MAX=24)。API_RESPONSE_CAP10→40、记录池 200→600、scope 结算等待 500→1200ms。记录仍只来自页面自身响应(frame_main/实测 status 判定不变),不认企业/ATS、不拼 URL、不注入请求。② Hotjob A3(
scan_all.grab_hotjob):按grab_beisen同规在pageData[]循环内产api_record十键(native_id=响应原始postId;http_status=当页实测,拿不到不产、绝不补 200;record_locator=当页下标;record_snapshot=api_record_snapshot(x,"postId");模板https://{host}/{tid}/pb/posDetail.html?postType=campus&postId={native_id})。判据零放宽(A3 仍需template_exact)。③ 契约/留痕对齐(
site_scope.py):countersapi_responses留痕 cap 10→40,与观测面同批响应可见。实证(隔离 E2E,不动
_scan):复星(/campus/jobs)A1 74/74(原 20/74)、A3 74/74、DLV 74/74 ⇒ YYZ 准入 2/入报 2、LQP 准入 1/入报 1(原先 3 条命中全被 A1 轴②拦截);先声(hotjob)A1 268/268(原 20/210)、A3 268/268proven(template_exact)(原 0/210no_api_record)、DLV 268/268 ⇒ YYZ 准入 4/入报 4、LQP 准入 13/入报 13(17/17 全入报)。测试:新增
test_hotjob_api_record.py20 项(正例十键/强度 template_exact/契约受理/无状态不产/分页 locator/透传);test_platform_api_scope49/49 复跑;全量回归见 §4。未做(如实登记):信达官方入口为第三方 51job 专场页,
CAMPUS_51JOB_COAPI_KEY未配置(_ex_51job_api实测no_key,属配置缺失非代码故障)⇒ 通道不可运行,未伪造归属;最小规范差异(PLATFORM_ACTIVITY_SCOPE)为 PROPOSAL,待授权。同 host 命名空间比对不含租户 token(_api_namespace_ok同 host 即真),共享主机族的 fail-closed 收紧方案为 PROPOSAL,本批只读复核未改判据。
2.2.23 = V0.4 §L 遗留事项关闭:集团级 API 岗位归属(PLATFORM_API_SCOPE + SCOPE_API_CALL_CHAIN)(2026-10-26):
事由:主理人下达《V0.4 第二期执行计划 v2.0》§L——A 类 52 家页面无 DOM 岗位锚点(JS 卡片非
<a>),现有两条 A1 路径结构性不可达;七项关闭条件全绿才标记完成,不得以「计划已更新 / 枚举已新增 / 单测全绿 / 纳入 P2-1」结案。① 观测面补齐(
verify_links.js):scope 模式新增api_responses[](每响应{url, status, frame_main, records},cap 3→10)——响应 URL / 实测 http_status(拿不到 ⇒ null,不补 200)/ 是否入口页主帧发起(iframe、第三方嵌入为 false,参与判定即失败);scope 初始等待 3500→6500ms(beisen 实证岗位 API ~5s 才触发)。② 路径③实现(
site_scope.py):PLATFORM_API_SCOPE + SCOPE_API_CALL_CHAIN四条件(入口页主帧发起且实测 200 的 API 响应 ∧ 命名空间一致(同 host,或同可注册域∧租户 token 相符)∧ 记录无跨命名空间 host 型取值 ∧ 身份键在该 API 记录池);集团级粒度,不要求分公司/siteId;分页完整性归 Coverage,不参与归属判定(分离原则)。失败 basis 精确到api_namespace_mismatch/identity_not_found_in_platform_api_records等,fail-closed 不变。③ L 包补遗:入口链成立时一并评估已观测一跳目标页(入口预览池 + 一跳全量池双候选,
produce_site_binding入口池优先);站点级结论不变、判据不降(每池仍过四条件);counters 留痕 cap 3→10 对齐观测面(判定用完整链、留痕不能只剩前 3 个——先声实证链共 5 个响应、listPosition 排第 4)。④ 机读契约(
data_contract.py):枚举与七定表增项(仅允许SCOPE_API_CALL_CHAIN),未登记类型 fail-closed 不变。生产实证(隔离 E2E,不动
_scan):先声(hotjob)A1 20/210 全链落盘;信达/campus/jobs入口 A1 21/86 ∧ A3 86/86 proven(template_exact) ∧ DLV 86/86 ⇒ YYZ 准入 1/入报 1、LQP 准入 3/入报 3(2027届初级招聘专员 J31021 五门全绿);联影 20/138、传音 1/177(入口+一跳池);负例正确 fail-closed(智元api_namespace_mismatch、德勤 host 不符、beisen 裸 host 门户identity_not_found);分页未完成 ⇒DISCOVERY_INCOMPLETE如实落盘且已独立验证岗位正常入报(分离原则实证)。测试:新增
test_platform_api_scope.py49 项;全量回归 66/66 OK / 0 FAIL(780.4s)。剩余缺口(如实登记):beisen 裸 host 门户入口子形态(台账入口观测面不可达 campus 列表,补救方向待主理人裁示);hotjob 不产
api_record⇒ A3 缺口(建议并入 P2-1)。关闭交付报告:《V0.4 §L 集团级 API 岗位归属 关闭交付报告_20261026》(七项关闭条件逐项核验全绿)。
2.2.22 = V0.4 第一期收尾批次:A1 生产路径修复(计数取数点 / 入口一跳 / 分页核验)(2026-10-25):
事由:主理人下达《V0.4 第一期收尾批次:A1 生产路径与计数、分页修复》(五项任务 + 六项完成条件)。
① 计数声明取数点修复(F1):
verify_links.js在锚点分类后剔除岗位条目卡片文本再取计数声明——GE#/jobs的「10」经实证是岗位卡片 JD 内文「允许6个月内投递10个职位」被(d+)s*个?职位捕获,不是「10 行/页」(同页页长实为 30 行/页且不匹配任何计数模式);判据强度不动(唯一计数声明 / 计数语义一致 /declared == job_anchors三条件不放宽)。② 入口到列表路由一跳闭包(F2,第四批 B-1 遗留 + 本批接线):入口页不是可闭合列表时,沿同 host ∧ 同租户路径前缀的一跳候选再核验(
hop_eligible/entry_hop_eligible/_eval_hops/tenant_prefix_ok);不按企业名写特例、不盲拼路由、不凭同 Host 认定归属。③ 分页核验(F3):
declared > job_anchors > 0∧ 声明唯一 ∧ 非分面时逐页观测,按 href 去重累积,零新增即耗尽;声明数字不当上限(恒瑞实测声明 1024 实际 420);未耗尽 ⇒pagination_incomplete, Coverage 如实标记不完整。生产实证:GE 租户根入口经一跳闭合
declared=5==job_anchors=5(A1 5/5);芯驰租户根入口无可用一跳 ⇒ A1 诚实不成立(nav_closure_failed:no_count_declaration),LQP 命中 1 条被「A1站点归属未证」拦截;#/jobs入口下芯驰 A1∧A3 7/7、DLV 7/7、准入 1/入报 1,GE A1 5/5(修复前 0/5),思特威分页 4 页耗尽accumulated=79==declared=79、A1 79/79、DLV 79/79、准入 1。附带修复:
_paths.validate_workspace卡清单改按被校验 workspace 解析(本批工作区新增 LQP 备份卡暴露的 ambient 漂移缺陷,selfcheck C2 曾误报 FAIL),新增test_workspace_validation.py10 项锁死。全量回归 65/65 OK(645.3s);冻结基线
_scan266/266 逐文件哈希不变(聚合cb6ef618…a96)。
2.2.21 = 工程验收闭环接入:contract-to-production-acceptance(2026-10-24):
事由:主理人下达《为 campus-search-daily 建立可验证的工程闭环验收机制》。
新增用户级技能
contract-to-production-acceptance(A–G 七步闭环 +
delivery_gate.py四态门禁 + 历史缺陷回归),并由本节 §0.2 接入本包工程主入口。不改任何业务判据与生产代码行为。
| # | 改动 | 落点 |
|---|---|---|
| 1 | §0.2 工程任务强制验收闭环(A–G + 门禁命令 + 不得交付条件) | SKILL.md §0.2 |
| 2 | 验收技能与工具链(门禁 / 失败注入测试 / 历史回归 / git hook) | 兄弟技能 contract-to-production-acceptance/ |
2.2.20 = V0.4 收口第三批:API 岗位身份证据接入 A3(2026-10-24):
事由:主理人交来《V0.4 第一批次收口 · 第三批:API 岗位身份证据接入 A3》,要求把扫描时已在手的平台 API 岗位记录接进 A3 判据,并明确「A3 来源证据是工程问题,由实施方先查证、设计并实施」——不再上呈技术路线选择题。核心纪律:Evidence 必须来自真实运行、可回溯原始 API 记录,不得事后依据
detail_url反向编造,不得把 API 来源证据伪装成详情页 DOM 证据。做了什么:
- 新 Evidence 类型
PLATFORM_API_JOB_RECORD(第 9 类,无正面结论):十键run_id / api_url / request_scope / platform_family / native_id / id_field / detail_url_construction / identity_ref / http_status / record_digest全非空,http_status必须实测 100–599 整数(绝不补 200);与DETAIL_PAGE_IDENTITY同规要求identity_ref存在;不进入basis_evidence_type/ 关闭证据链 /api_missing派生。url_binding增加api_record_evidence_ref:非空时listed_detail_url可缺省(仅限binding_source=PLATFORM_ID_MAPPING);append_url_binding落账做引用完整性三段校验(证据存在 / 类型正确 /identity_ref相等),任一不满足即raise。- 生产者接线:
grab_beisen(Id)与_ex_moka_api.grab(id,fragment 承载)逐 job 附api_record;_norm/_mk_candidate/_resolve_entity全程透传;identity_ledger.persist③b 节以稳定 refapirec:{run_id}:{identity_ref}:{native_id}落 Evidence 并回写verification.api_record_evidence_ref。其他家族不擅自扩展(按任务书「不得外推」)。- A3 双路消费:
derive_binding_status(..., api_record_proven=)⇒a3 = url_binding_proven ∧ (page_identity MATCHED ∨ api_record_proven);_api_record_proven六条件(PLATFORM_ID_MAPPING / ref 存在 / 证据可解析 / 类型正确 / identity_ref 相等 / native_id 出现在 URL)+ 页面 CONFLICT 优先否决;api_url_match_strength三态(template_exact/native_id_substring/no_match)。- §13.3 A3 四 铁律落地:API 路径
listed_detail_url一律为空(新增_api_path_url_binding为唯一构造器,回归锁test_api_path_leaves_listed_detail_url_empty);观测预算耗尽(not attempted)分支同样落绑定,A3 不得无据成立。- A1 取数点缺陷修正(E4,重大发现):
verify_links.js增采declared_count_matches[]与facet_link_count_values[];site_scope.py条件③ 改为——声明值落在分面计数中 ⇒count_source_is_facet(不得报count_mismatch);页面存在多个互异声明 ⇒count_declaration_ambiguous。豪威/海光原「count_mismatch(14 vs 9)」两个数都不是岗位条数(14 是北京市分面),修正后 A1 仍不成立但理由如实。- 新增测试
test_api_record_a3.py(47 项,北森/Moka 双家族生产链正反例各 8 项)+test_site_scope.pyS2q/S2t 四项。验证:全量回归 64/64 OK / 0 FAIL / 0 SKIP(435.2s);隔离 E2E(
p3_20261024c,真实 canonical 入口,豪威 83 + 海光 17 = 100 岗)7 项核验全 PASS——API 证据 100 条全部落盘并被 A3 消费(via=api_record,proven(template_exact)),url_bindings100 条全PLATFORM_ID_MAPPING且listed_detail_url全空,A1/A3/DLV 来源分离、记录关联一致;冻结基线_scan266/266 逐文件哈希不变(aggregate_sha256=cb6ef618…a037)。未达成(如实登记):隔离 E2E 准入 0 / 入报 0,无正向交付样本——阻塞在 A1(两家站点均
NOT_OBSERVED,scope_unproven:nav_closure_failed:count_source_is_facet),不在 A3。A1 的合法证据类型(五类 binding_type)对「列表页不枚举岗位、岗位只从 API 返回」的平台形态无可用路径:北森记录OrgId21 个互异值非站点字段、BelongStoreId=null;MokasiteId=null、orgId是租户非站点 ⇒PLATFORM_SITE_FIELD不可用。此项为架构级缺口(需新增 A1 binding_type),不在本批授权范围,留待后续批次。
2.2.19 = V0.4 收口第二批:A1/A3 正向观测验证与验收表纠正(2026-10-24):
事由:主理人交来《V0.4 第一期收口第二批:A1/A3 正向观测验证与验收表纠正》,明确指出「工作还有遗留问题,要解决的是这个 skill 能帮学生找到真实有效的岗位深链」,要求以实际正向详情页为样本验证观测精度、澄清 21 条 STRUCTURED_STATUS 的证据性质、按已定规范优先级做受控正向端到端、并修正正式验收矩阵。核心方法是先证明观测器漏抓、再改提取器,禁止放宽证据强度、禁止仅凭 URL/标题/主机/企业名判 MATCHED。
A1 观测精度三项修复(均有地面真值):① E1
cross_host_links原来把政府备案(beian.gov.cn)、企业主页、新闻链接、普通外链一概计入「跨站切换」——根因是listLinks应用了inChrome过滤而crossLinks未应用(同一函数两套标准)。改为通用语义观测(无域名黑名单):候选站点切换控件须满足 C1 站点集信号(标签/role/类名含 site/region/locale/country/language/tenant/store 等站点语义)或 C2 切换文本信号(切到/切换到/switch to/select site 等),且导航区归属排除 nav/footer/aside/header boilerplate;同时新增cross_host_anchors全量原始事实(不丢失原始信息,只改定性)。② E2declared_count探针全 None。先从原始 HTML/DOM 证明页面确有计数声明(汇顶goodix.zhiye.com/campus/jobs页<h2>共 36 条记录</h2>;不是豪威——豪威修复后实测declared_count=14,那是「北京市 共14个职位」分面计数,见 2.2.20 E4)而提取器漏抓 ⇒ 补「共N条」「在招职位N个」「N个在招职位」三类通用表达;未放宽SCOPE_NAV_CLOSURE证明条件,无声明仍如实记None、不推算不补造。③ E3SITE_KEY_RE把locationFlexibility/workLocationOption等岗位属性当站点归属字段 ⇒ 站点字段恒定性判别器改为「站点词表 ∧ 取值跨记录恒定」(站点/租户标识是列表属性,同列表内恒定;岗位属性逐条不同)。A3 详情页身份观测两项修复:① A3-1
_main_element无main/article/[role=main]时返回空 ⇒ 80/80 快照取不到主区 ⇒ 补body回退(main_region_source=body_fallback)。② A3-2 飞书等 SPA 1MB HTML 快照被截断、<main>被切掉 ⇒ 补rendered_main_text(SPA 渲染后主区文本)兜底,取不到仍如实no_strong_region。A3 全量正向探查(决定性证据,任务 3 前提被推翻):对冻结基线全部 149 家带详情 URL 的企业做真实浏览器探查 + 离线复放(147 家有渲染 DOM 原件;埃森哲、壳牌探针挂起、无原件,如实记
missing_html):MATCHED 0 / NOT_OBSERVED 149 / CONFLICT 0。12 家「URL 身份键出现在 HTML」经逐一核对全部是 URL 表达或非身份属性——<link rel=canonical>(ABB)、JSON-LD"url"(宝洁)、<meta name=mobileUrl>(汇顶/贝达/舒泰神)、微博分享 URL(中芯国际)、登录returnUrl(科伦博泰)、Moka 导航 href(景嘉微/PwC)、moseekerloginUrl/fromUrl、阿里 JSONP 回调、宝马pid=收藏按钮属性——均被 §3.1 ①/② 明文排除;页面主区确实声明的稳定编号(J11889/8431/NO.2711/A170211)与 URL 平台内部 id 属另一套编号体系。⇒ 「观测器漏抓身份信息」这一前提不成立,故未改 §3.1 身份判据、未放宽 MATCHED 路径。E4(本轮我引入的生产级回归,如实登记):E2 把
pickDeclaredCount提到模块作用域供单测,而page.evaluate回调在浏览器上下文执行、Node 模块作用域常量不可见 ⇒ReferenceError⇒ 整个rec.scope缺失 ⇒ A1 观测有效性闸全灭(83/83list_observation_unavailable)。纯函数单测全绿但从不执行浏览器路径,虚假信心。修复:经caps传可序列化COUNT_PATTERN_SPECS;新增TestJsScopeBrowserContext4 项真跑verify_links.jsscope 模式(本地 file:// 夹具)的守门测试(30 秒可复现本缺陷)。任务 4(21 条 STRUCTURED_STATUS 正名):21 条全部是
run_coverage.py:140-146产出的 LIST 页解析结果证据(obs 引用 0 条、verdicts 引用 0 条)⇒ 原报告措辞不准确,是 A1 范围观测而非岗位状态证据,已正名。受控正向端到端(隔离工作区
_scratch/iso_ws_v04b2_20261024,3 家异源平台,两轮):修复前 83/83scope_unproven:list_observation_unavailable(缺陷假象)⇒ 修复后失败原因变为真实数据事实nav_closure_failed:count_mismatch(declared=14,list_links=9);DLV 100/100 通过、deep_link L2_RECOVERABLE→L1_HAS、DL5、传输失败 0;A3 全NOT_OBSERVED(body_fallback,A3-1 生效);学生匹配 0/100(student_match全 false,既有 B3 语义未达标缺口);日报准入 0 / 入报 0。⇒ 无真实岗位通过准入进入日报,未制造样本。验证:全量回归 63/63 测试模块 OK / 0 FAIL / 416.1s(含新增
test_a1_scope_precision19 项——E1 语义 5 / E2 计数 4 / E3 恒定性 3 / JS 纯函数 3 / 浏览器上下文 4;test_a3_region_source20 项);冻结基线 266 文件 SHA256 复验 0 mismatch。★ 待主理人裁定(未自行放宽):① ATS 平台用 URL 内部 id 作岗位标识而详情页展示另一套人工编号 ⇒ 无法泛化出 A3 正向样本;替代方案(§1.2 身份键派生规则增补 / 页面编号仅作佐证 / 修订 §3.7 准入 / 分平台接官方 API)需主理人裁定。② 第 1—9 步正式验收矩阵已按五维重写(见工作区《V0.4_第二批_正式验收矩阵与最终报告_20261024.md》)。
回退:
git revert本提交;test_a1_scope_precision.py/test_a3_region_source.py为新增测试可单独移除;E4 修复改回模块作用域引用即回到缺陷态(不推荐)。
2.2.18 = V0.4 收口文档核查整改版(三类生产接线缺陷修复 + 受控运行实证)(2026-10-24):
事由:主理人交来《V0.4 第一期验收收口:生产接线与真实链路验证》,要求①核查文档所述是否事实;②排查是否还有未做完的工作。核查结论:文档四条事实陈述全部属实,但把两项「实现未完成」写成「已完成未联网验证」;另在受控运行中暴露一项文档完全未提及的更严重缺陷(DLV 传输层无分块 ⇒ 大厂整批超时)。
修复:① 任务 1(
run_coverage未进生产控制链)已于 2.2.17 整改,本轮经真实受控运行实证闭环(汇顶 attempt1 INCOMPLETE → 强制浏览器升级 → attempt2 COMPLETE,30 jobs、COUNT_RECONCILE 30/30;智元 INCOMPLETE ⇒action=mark_incomplete、may_mark_completed=False、may_read_as_confirmed_empty=False——覆盖事实真实参与完成性决策,非 scan 结束后置转换)。② 任务 2(身份记录未生产落盘):新增engine/identity_ledger.py——从 canonical 链真实事实构造 §1.2 Identity Record(身份键复用job_review.derive_entity_identity,不另造第二套规则、不把归属拼进身份键),按引用完整性顺序 append-only 落 ContractStore,回写jobs[].identity_ref;纪律:不新造身份(无 source_job_id / 无已登记规则 URL / 无完整三元组 ⇒ 如实skipped)、不覆盖(append-only,改记 sighting)、归属修正才写(无 evidence_ref ⇒attribution_skipped,不为凑记录造证据)、失败可见(errors可定位)。③ FIX-5(新发现):dlv_verify._run_verify_links原把单家全部候选一次性交给一个 Node 子进程,而--timeout是整进程超时(含 Chrome 启动 + 导航)⇒ 候选数大(先声 263 / 九号 262)必然触顶 ⇒ 整批记 transport_failed;改为按dlv_chunk_size()(默认 25,envCSD_DLV_CHUNK覆盖)分块,每块独立子进程、各自完整 timeout,单块失败只 fail 该块——不丢候选、不改判据、原序拼接、长度严格一致。④--scan-dir三段解析不一致(scan 按 Workspace 根 / verify-dlv 与 report 按 CWD ⇒ 受控运行 report 段「扫描目录不存在」):新增_paths.resolve_dir_arg()唯一真源,三段统一。⑤ PR-01 Run Completion 未转发--scan-dir⇒ 阶段事实读空目录 ⇒attempted=0⇒ 把成功的受控运行误判 FAILED:update_scan_stage增scan_dir,launcher 提取并经唯一真源解析后转发。受控运行实证(canonical 入口
launcher.py scan实跑,隔离工作区 +--scan-dir,不触碰冻结基线):4 家 = 565 jobs(汇顶 30 / 智元 10 / 先声 263 / 九号 262);修复前 DLV_PARTIAL(probed=565 / completed=40=两个小批 / transport_failed=525=两个大厂,算术闭合)⇒ 修复后 DLV_OK(probed=565 / completed=565 / transport_failed=0),565 条DLV1=True、verified_at新鲜、deep_link=L1_HAS;身份台账 identities=565(全 NATIVE_ID、ref 唯一)/ sightings=590 / attribution=555 / obs=80 / verdicts=565 / run_coverage=6,join 0 失败;run_id 与重规划 Attempt 各自落账(#r0014/#r0014#a2)。仍未验证 / 缺口(如实登记):正向交付样本未取得——交付准入 0 条(YYZ 0/4、LQP 0/20,未准原因仅 A1+A3,修复前还有「DLV 未验证」、修复后该项消失 ⇒ 阻塞点已收敛)。A1/A3 为结构性观测缺口(观测精度问题,不涉及放宽证据强度):E1
cross_host_links未排除 nav/footer/aside(listLinks应用了inChrome而crossLinks未应用——同一函数两套标准)⇒ 系统性计入 ICP 备案 / 企业站 / ATS 厂商链接;E2declared_count6 家探针全 None;E3SITE_KEY_RE把locationFlexibility/workLocationOption等岗位属性误当站点字段;E5 SPA 详情页 ID 不在主身份区 ⇒ 80 条 DETAIL_PAGE_IDENTITY 全 NOT_OBSERVED。★ 待主理人裁定的规范分歧:执行清单 §8 明文「站点归属(A1)只做一次轻量校验」,当前实现是完整 §13.3 两轴绑定(严于第一期要求)——以何者为准属业务/架构裁定,按项目纪律未自行放宽。验证:全量回归 61/61 测试模块 OK / 0 FAIL / 260.5s(真实工作区,无跳过);冻结基线 266 文件运行前后各核一次 SHA256+size 全对上、聚合哈希
cb6ef618…a037不变;selfcheck C0 FAIL 为预先存在问题(8 个开发测试脚本 + 2 个_replay产物含机器专属绝对路径,本轮改动文件均不在列),单独记录。第 1—9 步结论:不能整体验收——可验收 = 第 1/4/5/7 步;链路贯通但无正向样本 = 第 6/8/9 步(准入 0);规范明确未要求本期 =
STRUCTURED_STATUS(§1.5 L215 明文允许不生产,565 verdict 全NONE即合规)与 A1 文档型三类(§13.3 七.4 是证据形态许可表、七.5 规定无证据不得建绑定)。回退:
git revert本提交;identity_ledger.py可单独移除(scan_one接线为纯旁路追加);DLV 分块改回单批调用即回到修复前行为。
2.2.17 = V0.4 第一期第 4 步整改版(运行级 Coverage 真正进入生产调用链)(2026-10-23):
事由:主理人指出上一版把第 4 步「有代码、有测试、未进生产调用链」记为「已完成未联网验证」是定性错误——这是实现未完成(代码 + 规范即可证明的缺陷),按授权应直接修复。经查证:
engine/scan_all.py(canonicallauncher.py scan唯一生产入口)对RunController/req_obs/DataStore的引用数均为 0,即生产链既不生产 run_coverage 也不消费它。根因(非"忘了接线"):§1.7-A
LIST_PAGINATION.result_fact强制len(page_req_obs_ids) == processed_page_count,且observed_jobs=PRESENT要求processed_page_count >= 1。canonical 链不产 req_obs ⇒ 合法覆盖写不出来,强行写只能是伪造。故整改必须从请求级观测开始,而不是把RunController直接塞进扫描链。要点:① 新增
engine/req_record.py——线程内请求采集器(mark/since/record/note_parsed/mark_probe/record_manual),纪律:拿不到http_status记None(绝不补 200)、note_parsed无对应请求即丢弃(不得凭空造请求)。② 新增engine/run_coverage.py——§1.7-A 生产 + 消费(build_observation_ledger/plan_paths/build_coverage/consume/derive),四条工程裁定 D-cov1..4 在代码留痕;路径 =SITE_ENUM(恒有)+LIST_PAGINATION(入口已观测且非收口态)+COUNT_RECONCILE(仅当来源声明总数)。③scan_all接线:http_get/http_post真实发起处记录、北森/华为分页循环按页挂载解析结果、探测请求(如北森 API 返回非 JSON 而真实列表在 HTML)不计入分页轨迹但仍以STRUCTURE_DRIFT留痕、无页级观测时按实测状态码记一次聚合取回、扫描异常分支同样 fail-closed 产出覆盖。④discovery_completion.derive_discovery_completion(rec, coverage=)增 §1.7-A 硬闸:run_completion != COMPLETE⇒ 不得判 C1/C2/C3(含「不得把未发现岗位解释为确认零岗位」),不拦 C4(C4 本身即"穷尽仍不足"的诚实结论,拦它会把它误降为 U1)。⑤ 事实补采:北森 API 早已声明totalPage却被丢弃 ⇒ 记入declared_pages,使declared_page_count有真实来源(未声明仍为 null)。未改动:13 态判定顺序、
job_presence/job_presence_in_scope语义、第 5 步 DLV、§3.7 准入、§3.8 话术、_scan冻结基线(只读)。验证:全量回归 38/38 测试模块 OK(含新增
test_run_coverage_prod29 项:契约形状 / 不得伪证 / 计数对账 / 声明页数 / 停止原因 / 收口态 / 消费闸 / 采集器纪律);job_state --self-test68/68;冻结基线 266 条 replay 0 diff(无 coverage 时行为与整改前逐条一致)、聚合哈希cb6ef618…a037不变;单家真实 E2E(汇顶科技,真实入口):产出 4 条 req_obs(3 条STRUCTURE_DRIFT探测 + 1 条JOBS_PARSED)、run_coverage.run_completion=COMPLETE(由COUNT_RECONCILE声明 30/实取 30 支撑)、消费动作stop、完成态RESOLVED_FOUND未被误降。影响面(旧数据 replay,如实登记):以 10-15 生产批 259 家为样本、按"旧记录缺请求级观测"的最坏假设回放,26 家(10.0%) 由
RESOLVED_FOUND转DISCOVERY_INCOMPLETE(其中 ABB 声明 176 条、实取 167 条 = 真实截断,旧口径误判为正常完成);新跑因补采declared_pages与逐页观测,实际影响面应更小。日报学生端内容不受影响(build_report不消费discovery_completion),变化落在--mode continue的续跑判定与内部账本。回退:
git revert本提交;新增两模块可单独移除,scan_all的采集为纯旁路(不改抓取逻辑)。
2.2.16 = V0.4 第一期(第 1–9 步)正向验收缺陷修复版(2026-10-23):
事由:对 V0.4 第一期 9 步做正向实施验收(从规范条款出发,不从日报结果倒推),核实三处「规范已明确要求、实现未落实」的差异并直接修复。均为收紧型改动(只减少误判为已证/已填的情形,不新增任何"已证"路径)。
要点:① §1.5
basis_evidence_type补 open 侧——原实现只由derive_closing_basis产出(closed专用),open恒落NONE,违反「open由STRUCTURED_STATUS支撑时须填之」;新增job_state.derive_basis(open_state, facts)为 §1.5 唯一对外生产者,与derive_open_state共用同一评估器(不复制第二套判据)。② A1 范围证明改逐类判据——data_contract.site_binding_scope_proven原只看site_scope_evidence ∈ {SCOPE_FIELD_MATCH, SCOPE_NAV_CLOSURE},与基线 §13.3 七定表「各 binding_type 范围证明必须逐一对齐」不符(等于"允许五种形态却只给三种列表验证方式");改为按binding_type查表:SITE_SCOPED_LIST⇒ FIELD_MATCH/NAV_CLOSURE;PLATFORM_SITE_FIELD⇒ 仅 FIELD_MATCH;文档/契约型三类(OFFICIAL_ALIAS_MAP/MIGRATION_RECORD/ATS_TENANT_CONTRACT)本期记录形状不含scope_statement_ref等载体 ⇒ fail-closed(不臆造绑定)。③ §0.3 资格三态 fail-loud——原_parse_eligibility/_assign_scope只记录卡上出现的键,缺键静默按「不限」执行(= 程序自补默认值);改为取值按三态词表归一(不接受此前未被识别为排除,已修)、无法归一即 fail-loud,并由SearchRequest.from_card对四个资格字段逐键校验完整性。未改动(经验收符合规范):
derive_open_state四步唯一顺序与六类证据逐类核验、第 5 步 DLV(65e630d已接受,git log 65e630d..HEAD -- engine/dlv.py零改动)、§3.7 准入三条件与「先过准入再合并」、§3.8 唯一话术与 §4.3 净化、学历边界(req_lv > stu_lv才排除)。验证:全量回归 59/59 OK / 0 FAIL / 0 SKIP(272.0s,
CSD_WORKSPACE真实工作区,无跳过);冻结基线_scan完整性复核 266/266 文件 sha256 逐一相符、聚合哈希cb6ef618…a037复现一致(未被本次改动触碰);真卡 T5(YYZ/LQP 四键齐全)+ T7 基线等价(baseline_zero_diff)在真实工作区通过。回退:
git revert本提交即可;三处改动互不耦合,亦可单文件回退(job_state.py/data_contract.py/param_card.py+search_request.py)。
2.2.15 = V0.4 第一期收口版(Open-State 全量裁决 + A1 站点归属 + §3.7 交付准入 + 学生日报端重写)(2026-10-23):
事由:《V0.4 执行清单》第一期 9 步全部实施完毕(第 1–5 步在此前批次已交付,本版完成第 6–9 步并一次性整合交付)。核心变化:拟交付岗位全部(非抽样)进入 Open-State 唯一裁决链;新增 A1 站点归属生产证据生成器(site_binding,材料不足如实 NOT_OBSERVED,不伪造绑定);§3.7 学生交付准入闸(DLV 当前可用 ∧ A1 ∧ A3,404/410 零进日报);日报学生端按 §0.2/§4.2/§4.3/§3.8 重写(两板块制、唯一空话术、不展示负面/内部审计信息)。
要点:①
job_review.review_job_states面向全部拟交付岗位(sample=None生产接线),fetch_error→INSUFFICIENT_EVIDENCE分流;② A1 生产者只认强证据(nav 闭包 + 计数声明),scope_unproven如实留痕;③ 准入闸与 Open-State 裁决分离,delivery_admission()纯函数 + 行判据透传,render「先过准入再合并」;④ 学生端删除 ③④⑤ 区 / 附录覆盖对账 / JobMatch 概览,「新」=first_seen_run_id == 本次 run_id;⑤entry_frontier唯一消费者保持discovery_completion,日报侧移除后无双口径漂移;⑥ 观测预算边界修正(elapsed >= deadline_s):修复零预算 / 时钟 tick 内 elapsed=0 时预算耗尽仍发起一个 chunk 请求的缺陷(本机实测翻转 6%–60%,修复后 0/500 确定不发起)。验证:全量回归 59/59 OK(261.5s,边界修正后复跑);冻结基线(266 家)隔离 E2E 重出报(YYZ 71 命中 / LQP 263 命中,准入均为 0——旧数据早于第 5/6 步生产者,§3.8 唯一话术落盘,22 项负向不变量全过,输入批次聚合哈希不变);23 目标 step6 隔离探针(最终代码复跑,对账 12/12):
a1_established=0(NOT_OBSERVED×23,site_binding_produced=0 且原因留痕)、a3=3(page_identity MATCHED)、url_binding UNRESOLVED/NOT_OBSERVED 如实落位、closed/不招 0、basis(关闭证据类型)NONE×23,store_audit / cross_ledger / identity_recompute 全 ok(两轮间 2 条 Mars 岗位因真实页面观测波动由 uncertain 转 open/招,A1 仍 NOT_OBSERVED、§3.7 准入将排除——差异已如实记录)。已同步
VERSION.md/CHANGELOG_2.2.x.md(2.2.15)。
2.2.14 = V6.3 多层入口与时间预算改造版(三项任务书契约补齐 + U-4 开关下线)(2026-10-15):
事由:多层入口动态发现(BFS)与逐家 900s 时间预算接上生产扫描链;补齐任务书 §4.4.10.4.1/§4.4.10.3/§4.4.10.8.2 三项「设计已声明、代码未实现」契约;
CSD_GRADED_SEARCH_ON按主理人裁定正式下线(下线前零消费者 ⇒ 行为中性)。要点:① 多级入口前沿(子入口逐层追、过滤留痕、不静默丢弃);② 逐家 900s 为唯一企业级时间上限 + 启动前硬闸(剩余 <1s 不启动,时间用尽落 U1 不落 U2);③ 红线修复:前沿异常 ⇒
incomplete=True,不得再被判成 C1「完成」;④ 三项契约:discovered_at(ISO8601 UTC)/kind_guess(永不输出 job_detail)/limits(数量上限截断留痕);⑤ 两项工程修复(非 dictentry_frontier防御 + test_07b 子进程 PYTHONPATH 镜像)。试点:小米 85 号生产代码实跑 363.1s(<900s),4 个招聘入口全部追完、新增岗位 548,三项契约全部核验落盘。
回归:engine 472 OK;scripts 21 套件全绿。
已同步
VERSION.md/CHANGELOG_2.2.x.md(2.2.14)。
2.2.10 = V6.2 最终收尾版(关闭复验报告遗留缺陷)(2026-10-13):
事由:V6 最终复验报告遗留 6 项缺陷/未验证项(①
skip_loss()指标口径;②S-THIRD-PARTY/S-SEARCH-ENGINE适用性门与设计 §6.2 不一致;③ AC-8
closed无真实样本;④deadline_passed无生产者;⑤ 部署依赖未核实;⑥ 结论不得沿用修复前结果)。全部在 V6 范围内关闭,未新增 V6 外功能、未重写项目。
已同步
VERSION.md/CHANGELOG_2.2.x.md(2.2.10)。
2.2.9 = V6 复验补修版(AC-3④ 探索样本生产者 + ATS 指纹源 + T4 提前终止)(2026-10-13):
事由:2.2.8 收口后做最终复验时发现 3 处"永不触发的生产者 / 判据"与 1 处判据不成立,
全部属 V6 范围内未完成项(未新增 V6 外功能)。已同步
VERSION.md/CHANGELOG_2.2.x.md(2.2.9)。
| # | 修复项 | 落点 | 要点 |
|---|---|---|---|
| 1 | AC-3④ ② 适用性挑战样本的生产者 | scripts/adaptive_wiring.py | strategy_stats.record 早有 applicability_verdict 形参但无任何调用方传入 ⇒ ② 样本结构上无法产出。新增 run_applicability_challenge(受控试跑:仅 side_effect==["none"] 纯本地策略、零新网络请求;仅挑战 requires 已满足的可证伪者,requires 缺失者单列 structural 不计入分母);Planner 记录附 applicability_verdict 并经 _record_run_stats 透传 |
| 2 | AC-3④ 判据修正(禁凭空达标数字) | scripts/exploration.py | applicability_error_rate 原判据含 或 result_type ∈ {SUCCESS, PARTIAL},但本仓策略在空产出/输入缺失时仍返 verdict="SUCCESS"(gd_strategies.exec_embedded 实证)⇒ 任何"跑得干净"的试跑都被算作"实际有效",误判率恒 ≈ 100%。改为只认产出候选(new_candidates_deduped > 0) |
| 3 | AC-3① ATS 指纹源(跳级可达) | scripts/adaptive_wiring.py | S-ATS-PROBE 只调页面证据 probe_family(其 docstring 明确只服务"classify 未命中"入口)⇒ host 可判的 ATS 家族永不产出 ats_family,§5.2.1 ATS 跳级结构性不可达。改为两级指纹:host 权威家族表(ats_registry.detect,纯函数零网络)优先 → 页面证据兜底。真实轨迹已产出(指纹+顺序+跳过原因) |
| 4 | T4 提前终止(覆盖丢失) | scripts/discovery_planner.py | 原 if not new_keys: T4; break 无条件终止 ⇒ 任一策略失败(FAILED ⇒ delta={})即终止整链,其后仍适用的策略被记 NOT_EXECUTED_INCOMPLETE(= 缺失)。与 X3「便宜档全跑」冲突,且使 #3 的跳级必然踩雷。改为无新进展 且 适用策略已穷尽才终止(与 COMPLETION_REASONS["T4"] 原文一致) |
2.2.8 = V6 未完成项修复与复验收口版(2026-10-13):
事由:V6 独立复审(
deliverables/gstack/v6-review-campus-search-deeplink-2026-10-12.md)判 FAIL,两项硬缺口(AC-3 / AC-5)+ AC-2 独立调度闭环未删。主理人下达《V6 未完成项修复与最终验收授权》,
授权直接修复并复验。不新增 V6 外功能、不覆盖 live
_scan、不改变既定业务语义。已同步
VERSION.md/CHANGELOG_2.2.x.md(2.2.8)。
| # | 修复项 | 落点 | 要点 |
|---|---|---|---|
| 1 | AC-2 单一决策中心 | engine/graded_search.py(重写)· engine/scan_all.py | 删除 A→B→C→D 独立调度闭环(非注释/默认关);run_graded_search 降为纯委托兼容入口(一次 GD.discover(..., adaptive=True) + rep→meta 翻译);生产 scan_one 不再引用 run_graded_search/GRADED_SEARCH_ON;AST + 字符串静态核验唯一决策中心 |
| 2 | AC-3 停止规则唯一判据 | scripts/discovery_planner.py · scripts/cost_policy.py | cost_policy.stop_after 取代裸 success_condition;账本四分类(EXECUTED/NOT_APPLICABLE/SKIPPED_BY_STOP_RULE/NOT_EXECUTED_INCOMPLETE);ATS 显式跳级(L1 后 L2 前,ats_jump_order);探索双模式 + 两类样本指标;29 策略成本审计 0 偏差 |
| 3 | AC-5 V1 可靠性并入新链路 | scripts/execution_layer.py · scripts/adaptive_wiring.py | 预算硬闸(DeadlineExceeded)· 阶段超时(StageTimeoutExceeded)· 进程树回收 · 失败持久化(JSONL)· 断点续跑;在 adaptive 真链路做故障注入(F1–F7,9 项);异常不得静默转 jobs=[]/TRUE_EMPTY |
| 4 | §3 生产接线 | engine/scan_all.py | BROWSER_ESCALATE_ON 默认 1(不再默认永不执行);CSD_BROWSER_ESCALATE=0 可控关闭 |
| 5 | F 一致性 | VERSION.md · CHANGELOG_2.2.x.md · SKILL.md §15 | 四源版本号统一为 2.2.8;test_scan_continue.py 桩对齐 resolve_report_year;历史证据文件(含已删字段 facts_source)原样保留,另出新版时间戳产物 |
2.2.0 = Profile-first Target Architecture 收口版(2026-10-04):
事由:把 v2.1.5 之后的架构 / 机制变更收口为一次 minor release。核心 = Profile-first(任意数量 Profile 显式化)、
Evaluation / JobMatch / DLV / Report Dataset 分层、legacy 退役。已实施 + 单测全绿 + 生产日报已产出。
已同步
VERSION.md/CHANGELOG_2.2.x.md(2.2.0)。
| # | 改动 | 落点 |
|---|---|---|
| 1 | Profile 显式化 —— Run 对象(profiles 空即 fail-loud);参数卡动态 glob(删 DEFAULT_CARD_FILES);report_year 动态 | engine/run_model.py(新)/ _paths.py / param_card.py |
| 2 | Evaluation 分层 —— canonical evaluate_job / evaluate_job_across_profiles(消费 Card.scope_match / student_match,不重实现规则) | engine/evaluation.py(新) |
| 3 | JobMatch 关系层 —— Job × Profile 矩阵(produce_pair_match / build_job_matches / build_matrix;复用 R14 三值真值表) | engine/jobmatch.py(新) |
| 4 | DLV / Report Dataset —— build_dlv_dataset(Profile 无关);build_job_rows(按 Job × Profile pair verdict 过滤)/ build_matrix_rows / build_report_dataset | engine/dlv_dataset.py / report_dataset.py(新) |
| 5 | Legacy 退役 —— 删 engine/v2_pipeline.py(整文件)、judge_pools()、Card.match_title()、pool_match / matched_jobs 产出;RESULT_COLS 调整 | engine/scan_all.py / param_card.py / build_report.py |
| 6 | Profile 硬编码清除 —— 去 card_map["YYZ"] 字面量、去「YYZ 优先」、resolve_profiles | engine/scan_all.py / launcher.py |
回归红线(零改动):13 态 derive() / P0 verdict / F8 真值表(R14)/ DLV 业务语义 / Discovery / 参数卡词表。未纳入本版:Event Discovery(无实现);Entry Discovery / Discovery Strategy(库存在、未接生产)。
2.1.5 = SkillHub 安全整改(R1 密钥外部化 + R2 TLS 强制校验 + R3 references 脱敏)+ §16 安全铁律(2026-10-01):
事由:SkillHub 审查指出三项静态风险 —— ① 51job 签名 KEY 明文硬编码;② 16 处 TLS 校验绕过;③ references 真实捕获 token。
处置:最小整改,仅消除静态风险,不新建治理层/白名单/开关;安全 HARD(不为兼容性重新绕过 TLS)。
已同步
VERSION.md/CHANGELOG_2.1.x.md(2.1.5)。
| # | 改动 | 落点 |
|---|---|---|
| 1 | R1 密钥外部化 —— 删明文 KEY,改 os.environ.get("CAMPUS_51JOB_COAPI_KEY");缺失显式 no_key → M_TO_SEARCH(无源码兜底、不落 TRUE_EMPTY) | scripts/extractors/_ex_51job_api.py |
| 2 | R2 TLS 校验恢复 —— 移除 16 处绕过(15×Python 关闭证书/主机名校验 + 1×JS 忽略证书错误),统一默认证书校验上下文 | engine/ 5 处 + scripts/ 11 处 |
| 3 | R3 references 脱敏 —— references/15 真实飞书 token → <REDACTED_..._会话级_已过期> | references/15 |
| 4 | §16 安全铁律 —— 长期强制规则(R1/R2/R3 + 安全 HARD + 范围纪律 + 验收闸) | SKILL.md §16 |
| 5 | 版本叙述防混淆 —— §15 加「当前版本真源 = frontmatter」横幅、1.x 条目标「历史」、沿革止于当前版本;selfcheck C0 增四源版本一致性校验 | SKILL.md §15 + engine/selfcheck.py |
回归红线(零改动):签名算法 / 51job 协议 / 其他提取器 / 纪律层八铁律 / 十三态 / deep_link 三值 / DLV 语义。安全 HARD 代价(记录):2 家证书损坏站点(安永 EY、奔驰)恢复校验后降级 M_TO_SEARCH,未重新绕过。
2.1.4 = C-01 生产 DLV 接线 + B 来源标注/跨源合并 + 回填加固(2026-09-30):
事由:全站
detail_url_verified恒为0—— 生产路径(scan_all.py:1253)硬编码 0,且 DLV 引擎只跑 POC 目录(
_scan_core_poc)、其输出未回填。生产数据流在「detail_url→ DLV」之间断裂。另:报告层缺少来源标注与跨源合并(同一岗位多源重复、来源不明)。
已同步
VERSION.md/CHANGELOG_2.1.x.md(2.1.4)。
| # | 改动 | 落点 |
|---|---|---|
| 1 | 新增 canonical post-scan DLV 阶段 —— 生产 detail_url → verify_links.js 事实 → eval_dlv() → detail_url_verified(DLV1 计数)→ derive_dl() → map_dl_to_deep_link() → 原子回写 | engine/dlv_verify.py(新) |
| 2 | verify_links.js 通用 hash-route 重探 —— 首次 page.goto 无 response(同源同路径 hash 路由)时先 about:blank 再重探,使 http_status 可判定;无任何企业/host/ATS 特例 | engine/verify_links.js |
| 3 | verify_links.js 代理策略修复 —— env 有 HTTPS_PROXY/HTTP_PROXY → --proxy-server,否则 --no-proxy-server;修「坏系统代理致需代理站点 ERR_TIMED_OUT」 | engine/verify_links.js |
| 4 | dlv_verify.py 回填加固 —— ①--resume(默认开,跳过已 verified_at 公司,断点续跑、幂等)②单家公司 verify_company 异常隔离(不写、可续跑重试,绝不连坐整批) | engine/dlv_verify.py |
| 5 | launcher 注册 verify-dlv 命令 | launcher.py |
| 6 | verify_run2.py 标 DEPRECATED(all-pass 语义与 C-01 的 DLV1 语义冲突;仅注释,无逻辑改动) | scripts/verify_run2.py |
| 7 | B1 来源标注 —— 新增 provenance_backfill.py,复用 target_resolver.resolve_provenance(A1 声明/A2 外链/A3 路径证据)加性写 official_host_provenance | scripts/provenance_backfill.py(新) |
| 8 | B2/B3 报告层 —— 来源芯片(官方/ATS/未证)+ 跨源合并折叠(同企业·城市·归一化标题合并,主链接优先官方已验证);B3 解冻(展示不要求 L1_HAS) | engine/build_report.py |
| 9 | detail_url_verified 语义冻结 = 抽样中 DLV1(可访问/HTTP200)通过条数(企业级、抽样范围);候选规则 = first dlv_all_pass 否则 fallback facts[0].dlv | references/33 §十一 |
| 10 | B3 边界显式化:provenance=UNKNOWN → DLV2=None → L1_HAS=BLOCKED_BY_B3,排除出 C-01 | references/33 §十一 |
回归红线(零改动):scan_all.py / _evidence_defs.py / orchestrator.py / ATS registry / P0 baseline / Runtime Guard / 十三态 / deep_link 三值。C-01 与 C-02..C-06、generic 分页/API 扩展解耦。
2.1.0 = V1 + V2 架构收敛版(2026-09-27):
单一 Skill:V2 指令层契约并入
campus-search-daily;11 个 Core 迁入受管engine/;V1 判据/提取器语义零改动;项目数据与 Skill 完全分离(Workspace contract)。
不创建 V3。
| # | 改动 | 落点 |
|---|---|---|
| 1 | 唯一路径真源 _paths.py —— SKILL_ROOT/ENGINE_ROOT/SCRIPTS_ROOT/WORKSPACE_ROOT 严格分离;消除全部 C:Users... / D:Users... 硬编码 | _paths.py |
| 2 | 唯一生产入口 launcher.py —— --workspace / CSD_WORKSPACE / schema 校验 / capability 诊断;缺输入显式失败 | launcher.py |
| 3 | 11 个 Core 迁入 engine/(v2_pipeline/orchestrator/scan_all/param_card/job_state/generic_discovery/adapter_hub/reverify_moka/build_report + verify_links.js/browser_run.js) | engine/ |
| 4 | V2 指令层契约并入 §1 —— Student Profile / Search Request / Scope / 四模式 / JobMatch 三值 / Failure 四态 / City-first / append-only / 能力矩阵 | SKILL.md §1 |
| 5 | 分层自检 C0–C4 —— Package Integrity / Import Isolation / Minimal Workspace / Offline Logic / Runtime Capability | engine/selfcheck.py |
| 6 | V2 references 并入(student-profiles / keyword-expansion / report-format);报告权威仍归 references/30 | references/ |
| 7 | 能力透明:Job-driven = FAIL-FAST;Incremental = KNOWN LIMITATION;不虚报能力 | §1.4 |
回归红线(零改动):八铁律 / 十三态数量与语义 / ev_level 语义 / deep_link 三值 / QC 语义 /ATS registry / V1 extractor / _evidence_defs / verify_deeplinks.py(Runtime Guard frozen boundary)。
—— 以下为历史版本(1.x 线,已归档;非当前版本,当前版本见本文档 frontmatter)——
1.2.0 = 深链发现六阶段 + DL 分级 + Prior-Art 前置闸版(2026-09-23):
触发事由:主理人提供《岗位深链自动发现机制 v1.0》,经华为端到端实测验证有效
(Stage A 读出路由与主键参数名 → Stage C 捕获真实接口 → 101/101 全量 gap=0 →
12/12 深链逐条实开通过 → DL5)。
实测暴露的真正缺口:
references/17早已登记华为完整配方(含网关租户别名头),但执行时没有强制检索既有知识 → 缺口是「检索与强制」,不是「配方不足」。
| # | 改动 | 落点 |
|---|---|---|
| 1 | 新增 references/33-岗位深链自动发现机制.md —— 深链发现方法论唯一总纲(六阶段 A~F / DL0–DL5 / DLV1–DLV5 / 四条禁令 / 发现即转验证 / ★降维映射 / 华为实证附录)。不取代 references/16/17 的具体配方 | references/33 |
| 2 | 新增 Stage D 搜索引擎反查 / E 第三方反查 / F 旧系统发现(此前无) | 同上 §一 |
| 3 | dl_level(DL0–DL5)第 5 个并列字段 —— 描述深链发现/攻坚过程成熟度;不参与十三态推导 | _evidence_defs.DL_LEVELS/derive_dl() |
| 4 | DLV1–DLV5 深链合格性五判(可访问 / 官方域 / 岗位名匹配 / 招聘身份 / 非列表页)。命名避让:V1~V11 已被 references/91 占用 → 一律 DLV 前缀。DLV3 为净新增(HTTP 200 ≠ 正确职位) | _evidence_defs.DLV_LEVELS/eval_dlv() |
| 5 | ★ dl_level + DLV → deep_link 唯一降维映射 —— deep_link 三值仍是交付口径唯一权威,不扩展不改名;DL5 非 L1_HAS 的充分条件(DLV 未全过 → L2_RECOVERABLE)。代码唯一定义处 map_dl_to_deep_link(),禁止任何文件自行重写 | _evidence_defs.map_dl_to_deep_link() + references/33 §四 |
| 6 | §7.0 深链攻坚前置闸 —— 八项触发条件 + PRIOR_ART_CHECKED/prior_art_refs 强制留痕;未执行则该家结论不得进十三态。首期接 qc_gate 为 WARN-only,不新增 QC 编号、不新增 BLOCK | SKILL.md §7.0 + _evidence_defs.prior_art_required()/check_prior_art() |
| 7 | 新增 scripts/discover_deeplink.py —— Stage A 静态 + Stage C 运行时探针;只出事实,dl_level 由 derive_dl() 计算;浏览器 CHROME_PATH env 优先 + 宿主 HOME 反推 + 候选 glob;代理走 HTTP_PROXY/HTTPS_PROXY | scripts/discover_deeplink.py |
| 8 | verify_deeplinks.py 最小改造 —— ①新增 --self-test;②输出事实(http_status/final_url/rendered_len/features_hit/title_matched/job_name_expected/job_name_actual);③新增 DLV3 岗位名匹配事实;④classify_result 保留但降级为「页面事实兼容性分类」,不得当作 DLV/dl_level 判定;⑤宿主 HOME 解析改 env → __file__ 反推 → 候选 glob,去除国内版硬耦合 | scripts/verify_deeplinks.py |
| 9 | validate_jobs.py:dl_level 入 OPTIONAL_FIELDS + 值域校验(缺失放行 / DL0–DL5 通过 / 其他 FAIL)。不动 REQUIRED_FIELDS、不动十三态 | scripts/validate_jobs.py |
| 10 | 存量修正:references/17 华为 Header 记录补独立复现、pageSize 记录补实测差异(标待复核,不删旧结论);references/16 结构修复(两个「## 四、」→ 四/五 + 列表残片归位);VERSION.md 安装位置改「随宿主版本及运行环境而定」 | 三处 |
回归红线(零改动):八铁律 / 十三态数量与语义 / ev_level 语义 / derive_ev() / QC11 语义 / 现有 ATS registry / 历史 REQUIRED_FIELDS / deep_link 三值。deep_link 不得扩展为六值。
1.1.0 = LLM 语义段与 QC11 落盘版(2026-09-23):
① 启用 LLM 语义判断段(scripts/llm_semantic.py + references/32-LLM语义判断规格.md)——此前 v1.0.0 宪法级「默认零 LLM」,本版按主理人裁定正式引入,但严格限定在规则初筛之后的候选岗位语义判断;链路固定为「程序确定性采集 → 规则初筛 → LLM 语义判断」。② 作用域改为代码硬闸:ALLOWED_TASK_KINDS=("semantic_judgment",) +DENIED_TASK_KINDS(13 项别名),黑名单/白名单外一律抛 ScopeViolation,不再只是文档纪律。③ 首轮调用预算 llm_semantic_max_calls=300(全局硬上限);达上限四条硬约束:不静默截断 / 不把未判岗位判「不符合」/ 落盘 LLM_LIMIT_REACHED+semantic_overflow /未判岗位保持 待审核(is_hr_related=null,非 false)。④ QC11 首轮 --qc11-warn-only:正常执行、输出告警、告警强制落盘(qc11_warnings.json + .md,落在 _scan 父目录)、不因告警丢弃结果;落盘报告含「升级 BLOCK 候选」表,供首轮跑完后逐条决定升级哪些条件。⑤ 非否定分类守卫(_evidence_defs.guard_non_negative(),14 项非否定条件 + 否定措辞拦截)——「没有发现岗位」≠「没有岗位」,达 LLM 上限/证据不足/访问失败单独分类,不得转成否定结论。⑥ SKILL 结构:新增 §12(LLM 语义判断),原 §12/§13/§14 顺延为 §13/§14/§15。纪律层(八铁律)零改动 —— 铁律八「否定须有正面证据」被 §12 与 QC11 双重机器化。
1.0.0 = 深链发现重构版(2026-09-23,由 campus-job-daily v4.9.7 改造而来):① ATS 注册表入包(scripts/ats_registry.{json,py})—— 家族→提取器映射从包外 scan_all.classify()硬编码收进包内,classify() 退化为「只消费不定义」;② 指纹表合入注册表同文件(不另立 FP_RULES,根除两侧漂移);③ 「识别≠支持」双状态显式化 —— supported:false 不再静默退回 generic,改为落并列字段 ats_recognized/ats_supported;④ 入口发现三级法补机器实现(scripts/discover_entry.py,此前仅有方法论零代码;含 __NEXT_DATA__/数据岛识别);⑤ Job URL 三元组判据(job_triplet,只 WARN 不 FAIL);⑥ 证据分级 EV0–EV5 (scripts/_evidence_defs.py,避让 entry_status.E0_OK 命名)+ QC11 结论—证据匹配闸(铁律八机器化,首轮 --qc11-warn-only);⑦ references 文件名编码修复(32 个,按 NNN 前缀恢复正确中文名)+ scripts/check_refs.py 防复发;⑧ QC 编号统一为 QC0–QC10(原 SKILL.md 与 references/30/22 三处不一致),并如实标注「自动实装 6 项 / 人工 5 项」;⑨ 修正 validate_jobs.py 的 method 枚举漂移(原缺 深链方法9~12 与 入口发现①~③,会把合法值误判越界);⑩ 新增 §0.1 包内外界线声明。纪律层(八铁律)零改动。
沿革(完整谱系,止于当前版本):
campus-job-dailyv3.9.0 → … → v4.9.7→
campus-search-dailyv1.0.0 → v1.1.0 → v1.2.0(1.x 线,2026-09-23)→ v2.1.0 → v2.1.1 → v2.1.2 → v2.1.3 → v2.1.4 → v2.1.5 → v2.2.0 → v2.2.1 → v2.2.2 → v2.2.3 → v2.2.4
→ v2.2.5 → v2.2.6 → v2.2.7 → v2.2.8 → v2.2.9 → v2.2.10 → v2.2.11 → v2.2.12 → v2.2.13 → v2.2.14 → v2.2.15(当前)。
2.2.2(2026-10-10)—— 成功判据更正
事由:主理人裁定——原文「本技能的唯一成功判据是职位详情 URL」表述错误,须删除。
更正:成功判据 = 「正确的职位详情 URL」,即企业 ↔ 岗位 ↔ URL 三者正确对应;
错误岗位混入日报 = 技能失败。
连带修正:§8.1 补「三元组齐备是必要条件、非充分条件」——形式完整 ≠ 正确。
依据:冻结数据实测存在错误岗位混入(NON_JOB 入口页 3 条;同一 URL 挂多家企业 6,996 个 / 实体 13,992 条)。
§16 安全铁律(SkillHub 整改结论,长期强制,不可违反)
本节为长期强制规则。后续任何 Skill 的开发、修改、扩展均不得违反。
安全整改的纪律是「消除已识别的静态风险 + 最小必要链路衔接」,不新建治理框架、白名单、注册表或开关。
§16.1 总则:安全 HARD,不可为功能妥协
- 任何安全控制(密钥保护、TLS 校验、痕迹脱敏)不得因「某网站无法访问 / 某功能需要 / 兼容性」而临时或永久关闭。
- 安全整改只做最小改动;不引入 TLS 例外系统、白名单、注册表、全局开关或代理适配逻辑到生产代码。
- 发现清单外的安全问题:只记录,不修改;超出本节范围须主理人另行授权。
§16.2 R1 — 密钥与凭证(禁止硬编码)
- 源码中禁止硬编码任何密钥、签名常量、token、密码、cookie、授权头。
- 外部依赖的密钥一律通过环境变量注入(51job 签名密钥:
CAMPUS_51JOB_COAPI_KEY)。 - 密钥缺失时,提取器须显式返回
no_key等「配置缺失」信号;调用方据此走M_TO_SEARCH,禁止落0岗 /TRUE_EMPTY/ 判EXTRACTOR_BROKEN。 - 禁止任何形式的源码兜底:常量默认值、回退到明文、示例/占位/历史明文值。
- 新增外部 API 依赖时,密钥契约按此条设计,不得新增硬编码密钥。
§16.3 R2 — TLS / 主机名校验(强制开启,零绕过)
- 所有 Python HTTPS 请求须使用默认的证书校验上下文(即同时开启证书校验与主机名绑定校验);浏览器侧须保留证书校验(不得关闭证书错误拦截)。
- 禁止以下任一等价绕过(无论以常量、参数或浏览器选项形式出现):
将证书校验模式设为「不校验」、将主机名绑定校验关闭、将请求级验证关闭、或在浏览器中忽略证书错误——以及任何跳过证书 / 主机名校验的等价写法。
- 不得因某站点证书过期 / 自签 / 缺失签发者而重新启用绕过。该站点据此降级为
M_TO_SEARCH或UNREACHABLE,如实记录证书问题,不修证书、不加白、不绕过。 - 禁止引入任何 TLS 例外注册表 / 白名单 / 开关 / 代理适配逻辑。
§16.4 R3 — references 敏感痕迹(禁止真实凭据)
references/中不得包含任何真实捕获的会话级 token、签名、cookie、授权头、个人隐私字段。- 历史痕迹一律脱敏为
<REDACTED_..._会话级_已过期>占位;脱敏后不得残留可复用凭据。 - 新增 / 修改
references/前先自查:是否含真实 token / 凭证 / 个人隐私;有则先脱敏再提交。
§16.5 验收闸(每次涉及网络/密钥/TLS 的改动必跑)
- 静态检查(全包 grep,零命中方可通过):
- 明文密钥字面量不存在;
- TLS 绕过模式(关闭证书校验 / 关闭主机名绑定校验 / 浏览器忽略证书错误 / 等价写法)零命中;
references/无真实捕获 token。
- 功能回归:
- 含密钥路径在「环境变量存在 / 缺失」两种状态下均不崩溃、不落
TRUE_EMPTY; - TLS 恢复后全包无新增绕过;原证书损坏站点如实降级,不新增绕过。
- 含密钥路径在「环境变量存在 / 缺失」两种状态下均不崩溃、不落
- 任意一项不通过 → 停止并报告,不得带病合并。