Commit Graph

3 Commits

Author SHA1 Message Date
43e2e1db2f refactor: renumber the CKA bank 1-102 with no gaps
Task ids used to jump 1-43 / 101-124 / 401-418 / 501-517. They now run
contiguously in the same order:

  1-43    unchanged (base and extra)
  44-67   hard pool          (was 101-124)
  68-85   Simulator Set C    (was 401-418)
  86-102  Simulator Set D    (was 501-517)

Every reference moved with its task: ids, solution keys, workspace paths
({WS}/qNN and the graders' hidden .qNN-* files), temp paths, the one
hardcoded id in code (Q56's derived canary weight), and Q-number
cross-references in the harness, README and the explainer. Each task's
paths were checked to carry only its own new number. History entries and
the local session state were remapped so past attempts stay attached to the
same tasks; retired set A/B ids keep their old numbers and match nothing.
weak-spots is regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mhxm4rsUfuE5HoytYbu2YW
2026-09-22 22:05:37 -06:00
55ab18f814 fix: repair the CKA bank and harness after a live audit; add Simulator Set D
Every changed task was seeded, graded untouched, solved and re-graded on a
separate kind cluster. The four sim sets were rehearsed as full sittings (real
baseline, seed everything, solve in order, grade at the end): A 150/150,
B 176/176, C 163/163, D 122/122. Every random-pool task was either passed in a
real session or cycled the same way.

Graders that could never pass, or passed for free:
  Q306 (local-path cannot resize; now graded as an in-place resize), Q314 (GNU
  grep prefixed file names), Q305 (plain `get events` has no SOURCE column and
  events expire; now managedFields), Q410 (kindnet DOES enforce NetworkPolicy;
  the expected answer is now derived from the CNI), Q35, Q212 (missing `]`),
  Q101 (`can-i create pods/exec` asks about a pod NAMED exec; multi-type get),
  Q109 (an emptyDir over nginx's /var/log crash-loops it), Q40 (TTL was
  measured at grading time), Q121, Q106, Q104, Q41, Q26, Q403, Q409, Q417,
  Q113, Q22, Q24/Q108 (flaky right after a rollout), and free points on
  untouched Q24/Q102/Q108/Q119/Q122.

Reference solutions: S[43], S[107], S[121], S[106] rewritten; S[116] (a
Completed Job pod still pins its PVC), S[119] (a pods quota equal to replicas
deadlocks the rollout); DNS checks use FQDNs; the explainer and exam guide
are corrected (etcd restore is etcdutl's job on 3.6+).

Cross-session leaks: the pre-session baseline now also repairs Q114 (the
kube-system NetworkPolicy and CoreDNS replicas), Q117/Q39 kubelet CA paths,
Q317, kubelet drop-in binary paths, a moved scheduler manifest, leftover
static pods and the default StorageClass. Q115 releases its fixed PVs from
claims left by earlier sessions.

Conflicts: `breaks` may be a list and `solo` keeps Q102's etcd restore out of
mixed sessions. Q118, Q5/Q103, Q26 vs the W1 taints, set A 203/204/208/212 and
set B 305/309 no longer sabotage each other. Q317 now disables only CSR
signing (the old break killed the whole controller-manager). Q110/Q311 no
longer compare against the whole cluster at submit time. Two delete/recreate
races in setups are fixed.

Harness: the weak list clears after two clean passes in a row, weak entries
show the latest attempt's failures, domain scores use the exam's own tasks,
history entries can be marked synthetic (entry 11 is), the web UI lists
every sim set, `./exam grade` refuses mid-exam (--force), preflight checks W1.

Set D (`./exam sim d`): 17 original killer.sh-style tasks, ids 501-517,
122 points - control-plane inventory, event forensics with crictl, a broken
kubelet unit, kubelet certificates, manual scheduling with the scheduler
stopped, Helm housekeeping with a stuck release, an enforced AND-vs-OR
NetworkPolicy, dnsPolicy and access-mode troubleshooting, and more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 21:59:35 -06:00
65c2fbfd43 feat: Simulator Set C - 18-task mock modelled on a commercial CKA sitting
`./exam sim c` - 18 tasks, 163 points, 120 minutes, exam rules. Built after a
23% result on a paid mock, so reruns cost nothing and the weak topics can be
drilled as often as needed.

Original scenarios, not copies, exercising the same techniques as an 18-question
sitting: hostPath PV/PVC bound by volumeName, data migration between claims onto
a Retain volume, Helm render-then-install, Gateway API header canary, RBAC with
the answer written to a file, probe/selector/targetPort repair, HPA v2 behavior
blocks, and three "write the output to an exact path" data-extraction tasks.

Ids 401-418, set="c", difficulty="hard". cmd_sim is already generic over SETS so
no harness change was needed; set-tagged tasks stay out of POOL and cannot leak
into `./exam start` or drills. CKA bank goes 101 -> 119 tasks.

Two scenarios are deliberately adapted, because the originals would destroy the
practice cluster:

  - 410 audits the installed CNI and applies a default-deny, rather than
    installing Calico over the running kindnet. The Flannel-vs-Calico
    "does this CNI actually enforce NetworkPolicy" judgement is kept as a
    written answer.
  - 413 plans a control-plane upgrade - versions, ordered command sequence,
    `kubeadm upgrade node` for workers - and never runs `kubeadm upgrade apply`.
    The grader checks the ordering, modelled on Q316.

Verified end to end: every task seeded, solved with its own reference solution
and graded, 163/163 across all 18, in four batches. Checks were also confirmed
to fail cleanly against an unsolved cluster rather than erroring.

Three environment facts cost a round of debugging and are now encoded in the
tasks and their solutions:

  - The StorageClass on this kind cluster is named `standard`, not `local-path`,
    and is WaitForFirstConsumer - a PVC stays Pending until its pod can be
    scheduled, which is what interlocks the two faults in 414.
  - Under rootless podman the host cannot route to node IPs, so a host-side
    openssl against a NodePort just hangs (rc=124). 417 probes TLS from inside a
    node via nx against 127.0.0.1:<nodePort>. Nodes have openssl and curl but
    not nc or wget.
  - hostPath PV data must be seeded on every node (401, 405), since nothing
    pins the pod to the node holding the directory.

Seeding all 18 creates ~24 pods, which on this host needs
kernel.keys.maxkeys raised above the 200 default or container starts fail with
"unable to join session keyring: disk quota exceeded".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NziZdvBvy7CpEAAbZNgp8i
2026-09-18 09:05:20 -06:00