fix: review findings F03-F06 — quotas, rule hierarchy and a validator that checks

F03 — application records
- Quota already removed with F02's tracker; verified uncapped and that
  "interview reached" survives a later withdrawal.
- Aker BP: application date confirmed 2026-07-29 by the user, settling the
  one-day conflict. Its Adjacent-despite-79 classification is kept, NOT
  reclassified: the user does not remember the rationale and judged it
  immaterial on a closed role, and silently reclassifying to make the
  arithmetic tidy is the exact objection the review raised. Recorded as an
  explicit override reason with a rubric version instead.

F04 — rule hierarchy
- Three levels stated in AGENTS.md and CLAUDE.md: immutable evidence rules,
  standing user preferences, market/employer presentation.
- Deliverables separated from QA. The .tex stays the artefact of record; you
  still compile, into the application's own output/ folder, because the user
  cannot approve what he cannot open.
- `resume_reference.md` said "Capgemini/Bundeswehr: include only when directly
  relevant", contradicting the standing never-include rule. Split and fixed.

F05 — a green validator now means something
- Per-claim `forbidden` wording is enforced. 14 of 26 claims carried such a
  list and NONE of it was checked, which is why "owned the full ML lifecycle"
  passed. Matching tolerates inserted adjectives: the real regression read
  "Built a decentralized Data Mesh" and one word defeated the literal list.
- Added identity (e-mail/phone), employer-date, placeholder and
  document-exclusion checks. Capgemini's omission rule now has a canonical
  home in claims.json instead of living only in memory and config.md.
- Registered Groovy and Snowflake as forbidden skills. Both were absent from
  claims.json entirely, so "forbidden" existed in prose with nothing enforcing
  it.
- PASS no longer reads as a truth certificate: it prints what it did not check
  — scope implications, bullet-to-claim support, whether a number is real.

F06 — the scanner stopped fighting the documents
- LaTeX comments are no longer claims; `% never claim Terraform` was a finding
  before, which taught the workflow to write around the checker.
- Markup, accent macros and umlauts are normalized, so `\textbf{Snow}flake`
  cannot smuggle a forbidden skill past a substring test and
  `Universit\"at der Bundeswehr M\"unchen` is recognisably a school.
- Honest denials pass in English and German.
- The triple-list cadence hint knew only English "and", so it silently did
  nothing on every German package. Advisory only, and now labelled as such.

Verification
- The six counter-proofs from the report are caught: 9 errors on one synthetic
  document, where the old scanner found none.
- All six packages built under current rules scan clean — SBB, NVIDIA, RUAG,
  Kdo Cy, Citadel, Aker BP. Four false positives of my own were found and fixed
  on the way there; each is now a regression test.
- 13 older packages do report findings. Those look like genuine historical
  violations and are deliberately NOT fixed here: F17 governs archives and they
  must not be silently rewritten.
- `tests/test_document_scanner.py` added. Full suite 31/31 pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
This commit is contained in:
dennisthiessenandClaude Opus 5 committed 2026-09-11 19:33:24 +02:00
1 parent afdef7eb94
commit fc5f3e49ba
8 files changed
+421 -31

No files matched your search

+23 -1
View File
@@ -702,9 +702,21 @@
"evidence": "pending-user-clarification",
"output": "forbidden",
"note": "RESOLVED 2026-08-27, and the answer is NO. User confirmed: Ansible playbooks lived in Git, but execution was PUSH-based out of Jenkins/GitLab pipelines - there was no pull-based reconciliation agent (Argo CD, Flux). That is version-controlled, CI-driven infrastructure automation, not GitOps. The word stays forbidden in every document. The SUBSTANCE is writable and should be written: 'versionskontrollierte Infrastrukturautomatisierung mit Ansible aus Git, ausgefuehrt ueber Jenkins-/GitLab-Pipelines'. The Kdo Cy JD names 'Pull-GitOps' explicitly, so precision here is an asset, not a loss."
},
{
"name": "Groovy",
"evidence": "none",
"output": "forbidden",
"note": "Named in the NVIDIA JD alongside Bash and Python. Bash was confirmed and added 2026-09-05; Groovy was explicitly NOT - it stays unverified. Registered as a skill 2026-09-11 (review finding F05) so the document scanner can actually catch it: it was previously absent from claims.json entirely, which meant 'forbidden' existed only in prose and nothing enforced it."
},
{
"name": "Snowflake",
"evidence": "none",
"output": "forbidden",
"note": "Repeatedly named in target JDs (SBB, Snowflake Inc. reqs). The honest substitution is Teradata, Oracle, Redshift and Athena/Iceberg - see the SBB session file. Registered 2026-09-11 (review finding F05) for the same reason as Groovy. Note this forbids CLAIMING the skill; naming Snowflake as an employer or as a JD requirement in prose is not a claim, and the negation guard in the scanner allows an honest 'no Snowflake experience'."
}
],
"global_forbidden_output_patterns": [
"global_forbidden_output_patterns": [
"petabyte scale",
"petabyte-scale",
"own the AWS data platform",
@@ -712,5 +724,15 @@
"customer-embedded delivery",
"formal model evaluation",
"3 consecutive years"
],
"document_exclusions": [
{
"term": "Capgemini",
"scope": "every resume, CV and cover letter",
"reason": "Standing user preference: six months only (Nov 2014 - May 2015); the user does not want the short-stay impression. The resulting gap in the visible chronology is INTENTIONAL and must never be 'fixed' or explained away. The visible record starts at Generali, May 2015, which is also what any 'over ten years' tenure wording is measured against.",
"applies_to_documents_only": true,
"note": "This is a DOCUMENT rule, not a conversation rule. If an interviewer asks directly what the first civilian role was, naming it plainly is correct - declining to name a former employer reads worse than a six-month stay.",
"source": "User-confirmed 2026-08-27 after it regressed into the RUAG C5I draft; given a canonical home 2026-09-11 (review finding F05), having previously lived only in memory and config.md."
}
]
}