# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this repository is

This is **not a software project**. It has no source code, build system, dependencies, or tests.
The entire repository is a single artifact — `README.jpg` (976×968 JPEG) — which carries a
multi-stage steganography/crypto puzzle authored by `author@picard1701.com`.

There is nothing to build, lint, or test. "Working in this repo" means decoding, extending, or
maintaining that puzzle chain. The embedded text explicitly asks the reader to *solve* it rather
than describe it.

## Toolchain

Everything below was verified on this machine:

- `exiftool` (`/opt/homebrew/bin/exiftool`) — reads the stage-0 clue
- `python3` with `numpy`, `PIL`, `scipy` — needed for the DCT extraction
- **`python3.14`** (`/opt/homebrew/bin/python3.14`) — stage-3 `star.py` requires this exact version
- `curl` — the stage-3 server rejects every other user agent

## The puzzle chain

Stage 0 — **Metadata clue.** `exiftool README.jpg`. The XMP/IPTC `Title`/`Object Name` field holds
the instruction: don't look for LSBs; DCT the luminance plane in 8×8 blocks and read the signs of
the low-frequency coefficients.

Stage 1 — **DCT sign steganography.** Convert to YCbCr, take Y, subtract 128, split into 8×8
blocks, apply an orthonormal 2-D DCT-II per block. For each block take the **8 lowest-frequency AC
coefficients in zigzag order** (skip DC): `coefficient > 0` → bit 1, MSB first → one byte per block.
The payload is **9× redundant**: each character occupies 9 *consecutive blocks in raster order*
(wrapping across rows — it is a flat stream, not a 3×3 tile). Majority-vote each bit across the 9
copies. 14762 blocks ÷ 9 = 1640 characters. Without the vote you get ~2 bit errors per character.

Stage 2 — **Poem → Morse → Base32.** The recovered text is a Star Trek poem containing a
`;`-separated Morse string. Decoding it (`-...-` is `=`, the Base32 pad) yields
`OBUWGYLSMQYTOMBREBSG65BAMNXW2IDTNRQXG2BAOEQCQR2FKQUQ====` → `picard1701 dot com slash q (GET)`.

Stage 3 — **The live quest at `https://picard1701.com/q`** (see below) returns the Vigenère key.

Stage 4 — **Vigenère.** The poem's ciphertext line, decrypted with the key from the quest FLAG,
gives the final plaintext.

## The `/q` quest — hard-won operational notes

A stateful, 5-question HTTP quest. GET only; `/q?sid=<session_id>&answer=<plaintext>`. One wrong
answer invalidates the session and you restart from question 1.

- **`WebFetch` does not work here.** The server answers non-`curl` user agents with a joke
  `266 User Agent Refused`. Use `curl`. It also asks for no `python requests`; driving `curl`
  through `subprocess` is fine. The server's own banner warns that sub-agents may not work.
- **Never retype the question strings.** They are 5 nested layers of encoding — outer layer always
  `b64`, inner layers randomized between `b64`/`b85`. Pipe them programmatically; a single
  hand-transcribed character silently breaks the decode. Recursively trying each codec at each of
  the 5 layers and keeping the branch that yields UTF-8 works reliably.
- **Timeouts:** ~60 s per question, unlimited for question 1, and only **20 s with a single attempt**
  for the last one. Automate questions 4 and 5 *before* answering question 3 — there is not enough
  time to improvise them.
- **Bare `/q` requests reset the session** and may return HTTP 429 if repeated.

### Questions 4 and 5 (`star.py`)

Both ask you to fetch `https://picard1701.com/star.py` — a freshly generated ~6 MB, ~20k-line
obfuscated Python file, downloadable once per question. The mechanism:

1. Extract the `voyager` variable and **double**-base64-decode it → `MAGIC: <TOKEN>`.
2. Run `python3.14 star.py <TOKEN>` — passing the token **without** the `MAGIC: ` prefix. With the
   prefix, or with no argument, the script prints only its decoy first line and nothing else.
3. The script prints two lines; the **second** is the answer to submit.

The file is inert — it contains no `os.system`, `subprocess`, `socket`, `urllib`, `open`, `eval`,
or `exec`. It only computes and prints. Still worth re-checking on each fresh download, since it is
regenerated server-side every time.

## Spoilers

Delete this section if you want to re-run the puzzle against a fresh agent.

- Quest answers 1–3: `James T. Kirk`, `NCC-1701`, `Leonard McCoy`.
- Vigenère key (from the quest FLAG): `JDUWZCBAOWZFBYIGVWSNY`
- Final plaintext: *"Genial le probleme est entierement resolu stop on se retrouve a neuf heures aux deux lobsters!"*
