Skip to content
RepoKnit

Understand any codebase.

Ask questions about a public GitHub repository and get answers that point to the exact lines they came from.

Try pallets/flask, fastapi/fastapi or expressjs/express. Indexing isn't live yet, so you'll land on a status page.

pallets/itsdangerous @ 672971dRecorded from the live API on 22 Oct 2026, not generated for this page

How does TimestampSigner reject expired signatures?

What the evidence did not show: The implementations of get_timestamp and timestamp_to_datetime, and how sign embeds the timestamp, are not shown in the evidence.

src/itsdangerous/timed.pyOpen in workspace
88 try:
89 result = super().unsign(signed_value)
90 sig_error = None
91 except BadSignature as e:
92 sig_error = e
93 result = e.payload or b""
94​
95 sep = want_bytes(self.sep)
96​
97 # If there is no timestamp in the result there is something
98 # seriously wrong. In case there was a signature error, we raise
99 # that one directly, otherwise we have a weird situation in
100 # which we shouldn't have come except someone uses a time-based
101 # serializer on non-timestamp data, so catch that.
102 if sep not in result:
103 if sig_error:
104 raise sig_error
105​
106 raise BadTimeSignature("timestamp missing", payload=result)
107​
108 value, ts_bytes = result.rsplit(sep, 1)
109 ts_int: int | None = None
110 ts_dt: datetime | None = None
111​
112 try:
113 ts_int = bytes_to_int(base64_decode(ts_bytes))
114 except Exception:
115 pass
116​
117 # Signature is *not* okay. Raise a proper error now that we have
118 # split the value and the timestamp.
119 if sig_error is not None:
120 if ts_int is not None:
121 try:
122 ts_dt = self.timestamp_to_datetime(ts_int)
123 except (ValueError, OSError, OverflowError) as exc:
124 # Windows raises OSError
125 # 32-bit raises OverflowError
126 raise BadTimeSignature(
127 "Malformed timestamp", payload=value
128 ) from exc
129​
130 raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)
131​
132 # Signature was okay but the timestamp is actually not there or
133 # malformed. Should not happen, but we handle it anyway.
134 if ts_int is None:
135 raise BadTimeSignature("Malformed timestamp", payload=value)
136​
137 # Check timestamp is not older than max_age
138 if max_age is not None:
139 age = self.get_timestamp() - ts_int
140​
141 if age > max_age:
142 raise SignatureExpired(
143 f"Signature age {age} > {max_age} seconds",
144 payload=value,
145 date_signed=self.timestamp_to_datetime(ts_int),
146 )
147​
148 if age < 0:
149 raise SignatureExpired(
150 f"Signature age {age} < 0 seconds",
151 payload=value,
152 date_signed=self.timestamp_to_datetime(ts_int),
153 )

claude-opus-5-5, 6 claims, all 7 citations checked against the retrieved code, $0.052, 13.1 s

Ask it live

Neither search found it alone.

The code behind that answer is the body of TimestampSigner.unsign. Vector search ranked it 14th and BM25 16th, and an answer reads the top 12 chunks. Turbopuffer runs both as one hybrid query and fuses the rankings, which put it 12th: just inside. Each fused row carries the rank it had in each list.

Recomputing RRF from the two lists reproduces all 12 of Turbopuffer's fused scores, in the same order (largest difference 1.8e-9, float rounding).

  1. 1timed.py:22-27V3 B1
  2. 2timed.py:53-54V1 B3
  3. 3timed.rst:1-28V8 B2
  4. 4test_timed.py:1-15V5 B7
  5. 5timed.py:170-228V9 B4
  6. 6test_timed.py:29-93V2 B13
  7. 7test_timed.py:78-85V4 B17
  8. 8timed.py:185-220V16 B5
  9. 9test_timed.py:34-43V6 B19
  10. 10timed.py:64-70V15 B12
  11. 11timed.py:56-62V18 B11
  12. 12timed.py:72-158V14 B16

timed.py:72-158TimestampSigner.unsignfused rank 12

Vector
rank 14, 1/(60+14) = 0.013514
BM25
rank 16, 1/(60+16) = 0.013158
Sum
0.026671 Turbopuffer returned 0.026671

Recorded from the live API on 22 Oct 2026 for the same question. Ticked rows are chunks the answer cites.Try other questions and weights in the lab

Understand how it fits together. Module and import graphs are parsed from the source, so every edge points at a real import statement.

Investigate with citations. Each claim in an answer links to a file and line range. Anything the code doesn't show is labelled as inference.

Measure retrieval, not prose. Score search against hand-labelled questions to see whether the right code was found before you trust an answer.

What works today

RepoKnit is early. The API, indexing worker and Turbopuffer index are live, with one repository indexed so far: pallets/itsdangerous. The demo workspace runs offline on a bundled fixture, and How it works explains the design.

Working

  • Questions about an indexed repository, answered by Claude with every citation checked
  • Vector, keyword and hybrid search in Turbopuffer
  • A retrieval lab that scores those search modes against hand-labelled questions and shows how hybrid fuses them
  • Daily limits per visitor and an overall daily cap on answers
  • A demo workspace and architecture explorer over a bundled fixture

Not built yet

  • Indexing a repository from this site (the operator queues it with an admin token)
  • Accounts and per-user quotas
  • Multi-step investigations for questions one search can't answer
  • Symbol graphs for TypeScript