尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Tender Tool turns your company documents, people and past-project evidence into SANRAL's complete technical and financial envelope packs - checked page by page against the tender's own rules. No AI blabber, nothing missing, nothing expired.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Multi-tenant SaaS for South African tender preparation (SANRAL, ACSA, SASSA), built first around
Sarel's own tenders. See docs/specs/Tender-Tool-Claude-Code-Handover.md for the build brief,
phase order and architecture requirements — read it before changing anything here.
docs/specs/ — the source-of-truth specs, pulled in verbatim from the Drive folder "Tender Tool":
Tender-Tool-Claude-Code-Handover.md — build brief and phase order. Read first.SANRAL-Tender-Automation-Specification.md — the SANRAL workbook-filling spec (sections 1–9,
the 12-point verification checklist V1–V12, open issues, questions for Sarel).SANRAL-Appendix-A-Source-Code.md — the same engine scripts in engine/, as markdown, for
reference against the spec's own commentary.Tender-Tool-Competitor-Feature-Deep-Dive.md — competitor research and the phased feature list.engine/ — the SANRAL workbook-filling engine, extracted from Appendix A (unmodified) plus
fingerprint.py (Stream 1, new).templates/samples/ — real blank SANRAL "Conventional Consultant Tender" templates, for testing
the engine against. SHA-256 verified against the hashes recorded for these files in Drive.fingerprints/ — stored template-family fingerprints (Stream 1 baselines). Generated by
engine/fingerprint.py, not hand-written.Sarel's rule: "There's always a chance a tender template has changed, so we must always check first." Run this before ever filling a workbook:
python3 engine/fingerprint.py <template.xlsm>
First run for a template family stores the baseline. Later runs compare against it and print
exactly what changed on any mismatch — sheet names/order, dropdown count per sheet, named ranges,
per-sheet cell-layout hash, macro presence/hash, or the whole-file hash. See the module docstring
in engine/fingerprint.py for the documented limitation (it fingerprints occupied cell references,
not lock/formula status — a tighter version is future work).
Open question for Sarel: running this against the 5 real Conventional templates supplied,
every file except the two R.334-030-2025.1F submissions (ran/ran1) flagged a macro-hash
mismatch against the first one seen. ran and ran1 are two submissions for the same contract
and matched exactly; R.343, R.352 and R.394 are each a different contract and each has a
different vbaProject.bin hash from the baseline (R.343 also differs in TEND 1X cell layout).
This may just mean SANRAL's own export re-compiles the VBA project (embeds a fresh timestamp/GUID)
per contract even when the macro source is identical — or it may mean these aren't all the same
template version. Either way the tool is refusing to guess, as designed; it needs a decision on
whether macro hash should be part of the family fingerprint or compared separately from the rest.
engine/discovery/list_tenders.py — pulls the full open-tenders list via the site's own
DataTables AJAX endpoint (confirmed: 137+ tenders, not the 10 the rendered page shows). No
auth, no personal data.engine/discovery/detail.py — per-tender metadata (file size/count, create/last-updated
dates) from the public detail page. No auth, no personal data.engine/discovery/download_documents.py — actually fetches a tender's document pack. This
does submit personal data (full name, company, phone, email) through the site's real
"Download Documents" form, via a real browser (Playwright/Chromium) clicking the real button —
not a captcha-solving workaround, just normal use of a reCAPTCHA v3 (invisible) protected form.
Requires --fullname/--company/--phone/--email explicitly; refuses to guess at identity.engine/discovery/run_discovery.py — the daily run: fetches the full list + detail metadata
for every open tender (free, no identity data), diffs against the previous run, and only
submits the download form for tenders that are new or changed since then — not all ~137
every day. Unzips each downloaded pack and runs fingerprint.py on every .xlsm inside.
Identity comes from a local --contact-file (see config/contact.json.example), never
committed, never hardcoded.Compliance check done 2026-10-15: robots.txt allows all paths for all agents; the published Terms & Conditions cover only copyright/disclaimer/linking — nothing about automated access.
.xlsm here — it drops the form controls and data validations.