Dashboardinstitutional-transition-labSession 0RsRJeRgksVA

Session 0RsRJeRgksVA

Full ID: 0RsRJeRgksVAwRSzB
Messages: 26
Distillations: 2
Time range: 2026-09-09 05:38:31 — 2026-09-09 05:57:27

Conversation (26 messages)

Perform a fresh, minimal, read-only security audit of only declared ZIP-size limit arithmetic for issue #4 in /home/byk/Code/institutional-transition-lab. This replaces a resource-accounting reviewer that returned empty twice. Never edit files or inspect governance records/codings/outcomes/reports/dates/detectors/source-adjudication.

Scope only: how central-directory file_size declarations are checked against per-member and total expanded-byte constants; exact boundary behavior; integer/negative/overflow/impossible values as exposed or byte-patchable; whether malformed declarations bypass limits before decompression. Do not inspect actual member read loops, CRC/content comparison, archive names/path/mode/encryption/count, regular-file reads, JSON/pins/hashes, or CLI output.

Review only relevant code/constants in src/institution_lab/governance_adjudication.py and narrow tests. Run small read-only probes. Return substantive evidence, never empty. Findings first with exact file:line references and PASS/CONCERN/MUST-FIX/BLOCKED labels; deterministic regression for every defect. End exactly MERGE or DO-NOT-MERGE.

gateway · 2026-09-09 05:38:31
result
Found 10 matches
/home/byk/Code/institutional-transition-lab/src/institution_lab/governance_adjudication.py:
  Line 67: MAX_ARCHIVE_MEMBERS = 128

  Line 68: MAX_ARCHIVE_MEMBER_BYTES = 16 * 1024 * 1024

  Line 69: MAX_ARCHIVE_EXPANDED_BYTES = 64 * 1024 * 1024

  Line 181: 			infos = archive.infolist()

  Line 182: 			if len(infos) > MAX_ARCHIVE_MEMBERS:

  Line 188: 			if sum(info.file_size for info in infos) > MAX_ARCHIVE_EXPANDED_BYTES:

  Line 189: 				raise ValueError("artifact expanded size exceeds limit")

  Line 199: 				if info.file_size > MAX_ARCHIVE_MEMBER_BYTES:

  Line 202: 					member_bytes = source.read(MAX_ARCHIVE_MEMBER_BYTES + 1)

  Line 203: 				if len(member_bytes) > MAX_ARCHIVE_MEMBER_BYTES:
gateway · 2026-09-09 05:39:20
result
<path>/home/byk/Code/institutional-transition-lab/src/institution_lab/governance_adjudication.py</path>
<type>file</type>
<content>
55: }
56: CLAIM_FIELDS = {
57: 	"record_class",
58: 	"event_kind",
59: 	"title",
60: 	"announced_on",
61: 	"effective_on",
62: 	"affected_scope",
63: 	"body_patch_relation",
64: }
65: MAX_INPUT_BYTES = 16 * 1024 * 1024
66: MAX_ARTIFACT_BYTES = 32 * 1024 * 1024
67: MAX_ARCHIVE_MEMBERS = 128
68: MAX_ARCHIVE_MEMBER_BYTES = 16 * 1024 * 1024
69: MAX_ARCHIVE_EXPANDED_BYTES = 64 * 1024 * 1024
70: 
71: 
72: @dataclass(frozen=True)
73: class VerifiedInputBundle:
74: 	pins: dict[str, Any]

(Showing lines 55-74 of 946. Use offset=75 to continue.)
</content>
gateway · 2026-09-09 05:39:29
result
<path>/home/byk/Code/institutional-transition-lab/src/institution_lab/governance_adjudication.py</path>
<type>file</type>
<content>
165: 	adjudication_schema: bytes,
166: ) -> VerifiedInputBundle:
167: 	_validate_manifest_identity(manifest)
168: 	computed = {
169: 		"artifact_sha256": _bytes_sha256(artifact),
170: 		"documents_file_sha256": _bytes_sha256(documents),
171: 		"coding_package_file_sha256": _bytes_sha256(coding_package),
172: 		"protocol_sha256": _bytes_sha256(protocol),
173: 		"coding_schema_sha256": _bytes_sha256(coding_schema),
174: 		"adjudication_schema_sha256": _bytes_sha256(adjudication_schema),
175: 	}
176: 	for field, value in computed.items():
177: 		if manifest.get(field) != value:
178: 			raise ValueError(f"input manifest mismatch: {field}")
179: 	try:
180: 		with zipfile.ZipFile(io.BytesIO(artifact)) as archive:
181: 			infos = archive.infolist()
182: 			if len(infos) > MAX_ARCHIVE_MEMBERS:
183: 				raise ValueError("artifact member count exceeds limit")
184: ...
gateway · 2026-09-09 05:39:40
result
No files found
gateway · 2026-09-09 05:39:57
result
No files found
gateway · 2026-09-09 05:40:18
result
/home/byk/Code/institutional-transition-lab/tests/test_governance_adjudication.py
/home/byk/Code/institutional-transition-lab/tests/test_model_policy.py
/home/byk/Code/institutional-transition-lab/tests/test_source_retrieval.py
/home/byk/Code/institutional-transition-lab/tests/test_source_enrichment.py
/home/byk/Code/institutional-transition-lab/tests/test_robustness.py
/home/byk/Code/institutional-transition-lab/tests/test_phases.py
/home/byk/Code/institutional-transition-lab/tests/test_oss_metrics.py
/home/byk/Code/institutional-transition-lab/tests/test_oss_ingest.py
/home/byk/Code/institutional-transition-lab/tests/test_llm_triage_compare.py
/home/byk/Code/institutional-transition-lab/tests/test_llm_event_probe.py
/home/byk/Code/institutional-transition-lab/tests/test_llm_candidate_triage.py
/home/byk/Code/institutional-transition-lab/tests/test_llm_benchmark_subset.py
/home/byk/Code/institutional-transition-lab/tests/test_llm_benchmark_gate.py
/home/byk/Code/institutional-transiti...
gateway · 2026-09-09 05:40:37
result
Found 13 matches
/home/byk/Code/institutional-transition-lab/tests/test_governance_adjudication.py:
  Line 65: 	with zipfile.ZipFile(paths["artifact"], "w") as archive:

  Line 66: 		archive.writestr("documents.json", paths["documents"].read_bytes())

  Line 67: 		archive.writestr(

  Line 703: 	with zipfile.ZipFile(artifact, "w") as archive:

  Line 704: 		archive.writestr("documents.json", documents.read_bytes())

  Line 705: 		archive.writestr("v1.2-adjudication-package.json", coding_package.read_bytes())

  Line 743: 	with zipfile.ZipFile(artifact, "w") as archive:

  Line 744: 		archive.writestr("documents.json", b"different documents")

  Line 745: 		archive.writestr("v1.2-adjudication-package.json", coding_package.read_bytes())

  Line 890: 		zipfile.ZipFile(paths["artifact"], "a") as archive,

  Line 892: 		archive.writestr("documents.json", paths["documents"].read_bytes())

  Line 913: 	with zipfile.ZipFile(paths["artifact"], "a") as archive:

  Line 915: ...
gateway · 2026-09-09 05:40:52
result
No files found
gateway · 2026-09-09 05:41:04
result
Found 5 matches
/home/byk/Code/institutional-transition-lab/tests/test_governance_adjudication.py:
  Line 271: 				"evidence_limitations": None,

  Line 423: def test_bounded_source_requires_explicit_evidence_limitation() -> None:

  Line 446: 	assert any("bounded evidence requires evidence_limitations" in error for error in errors)

  Line 919: 	with pytest.raises(ValueError, match="artifact member count exceeds limit"):

  Line 1017: 			"evidence_limitations": None,
gateway · 2026-09-09 05:41:51
result
<path>/home/byk/Code/institutional-transition-lab/src/institution_lab/governance_adjudication.py</path>
<type>file</type>
<content>
1: from __future__ import annotations
2: 
3: import argparse
4: import hashlib
5: import io
6: import json
7: import os
8: import stat
9: import tempfile
10: import zipfile
11: from collections import Counter
12: from contextlib import suppress
13: from dataclasses import dataclass
14: from pathlib import Path
15: from typing import Any
16: 
17: from jsonschema import Draft202012Validator, FormatChecker
18: 
19: from institution_lab.governance_coding import validate_response
20: 
21: DECISIONS = {"accept", "revise", "reject", "abstain"}
22: INSTITUTIONAL_CLASSES = {

(Showing lines 1-22 of 946. Use offset=23 to continue.)
</content>
gateway · 2026-09-09 05:42:38
result
member_exact [16777216, 0] member_reject False total_reject False
member_plus_one [16777217, 0] member_reject True total_reject False
total_exact [16777216, 50331648] member_reject True total_reject False
total_plus_one [16777216, 50331649] member_reject True total_reject True
underdeclared [0, 0] member_reject False total_reject False
u32_max_minus_sentinel [4294967294, 0] member_reject True total_reject True
u32_sentinel 4294967295
pack_u32 -1 error
pack_u32 4294967296 error
gateway · 2026-09-09 05:43:00
result
No files found
gateway · 2026-09-09 05:43:13
result
<path>/home/byk/Code/institutional-transition-lab</path>
<type>directory</type>
<entries>
.git/
.github/
.gitignore
.lore.md
.pytest_cache/
.ruff_cache/
.venv/
AGENTS.md
cases/
data/
docs/
node_modules/
package-lock.json
package.json
PROTOCOL.md
pyproject.toml
README.md
research/
schema/
scripts/
src/
tests/
uv.lock

(23 entries)
</entries>
gateway · 2026-09-09 05:43:29
result
?? src/institution_lab/governance_adjudication.py
?? tests/test_governance_adjudication.py
gateway · 2026-09-09 05:43:44
result
<path>/home/byk/Code/institutional-transition-lab/src/institution_lab/governance_adjudication.py</path>
<type>file</type>
<content>
150: 	if type(manifest.get("artifact_id")) is not int or manifest["artifact_id"] < 1:
151: 		raise ValueError("input manifest artifact_id is invalid")
152: 	for field, value in FROZEN_INPUT_PINS.items():
153: 		if manifest.get(field) != value:
154: 			raise ValueError(f"input manifest does not identify frozen issue #4 input: {field}")
155: 
156: 
157: def _verify_input_payloads(
158: 	manifest: Any,
159: 	*,
160: 	artifact: bytes,
161: 	documents: bytes,
162: 	coding_package: bytes,
163: 	protocol: bytes,
164: 	coding_schema: bytes,
165: 	adjudication_schema: bytes,
166: ) -> VerifiedInputBundle:
167: 	_validate_manifest_identity(manifest)

(Showing lines 150-167 of 946. Use offset=168 to continue.)
</content>
gateway · 2026-09-09 05:50:55
result
member_at_limit [16777216] (True, True)
member_over_limit [16777217] (False, True)
total_at_limit [16777216, 16777216, 16777216, 16777216] (True, True)
total_over_limit [16777216, 16777216, 16777216, 16777216, 1] (True, False)
underdeclared local_size 1 central_size 0 exposed 0 gate (True, True)
missing_zip64_extra_sentinel 4294967295 (False, False)
python_sum_exact 8589934590 True
u32_unrepresentable -1
u32_unrepresentable 4294967296
gateway · 2026-09-09 05:51:22
result
zip64_u64_max 18446744073709551615
member_reject True
total_reject True
sum_two_exact True
u64_negative_unrepresentable True
u64_too_large_unrepresentable True
gateway · 2026-09-09 05:52:03
result
declared_sizes [1, 1, 16777217]
production_preopen_size_checks_pass True
gateway · 2026-09-09 05:52:23
result
No files found
gateway · 2026-09-09 05:53:25
result
truncated_zip64 BadZipFile Corrupt zip64 extra field. File size not found.
gateway · 2026-09-09 05:54:06
result
compressed_archive_bytes 16576
local_uncompressed_size 16777217
central_sizes_exposed [0, 1]
production_preopen_size_checks_pass True
gateway · 2026-09-09 05:54:43
result
open_before_read accepted declared 0
gateway · 2026-09-09 05:55:17
result
 M pyproject.toml
 M uv.lock
?? .lore.md
?? AGENTS.md
?? cases/review/oss-governance-adjudication-v1.inputs.json
?? cases/review/oss-governance-adjudication-v1/
?? schema/governance-adjudication-v1.schema.json
?? src/institution_lab/governance_adjudication.py
?? tests/test_governance_adjudication.py
gateway · 2026-09-09 05:56:20
result
local_flags 0
central_flags 0
local_uncompressed_size 16777217
central_uncompressed_size 16777217
gateway · 2026-09-09 05:57:27

Findings

  1. MUST-FIX β€” a forged central-directory underdeclaration bypasses both size gates.
    infolist() supplies central-directory values at src/institution_lab/governance_adjudication.py:181. The aggregate check trusts those values at :188, and the selected-member check trusts them again at :199. Member opening follows at :201, with no prior declaration-consistency check.

    A read-only probe created a 16,777,217-byte member, then changed only its central-directory size to zero. The local header remained 16,777,217 with the data-descriptor flag clear. Python exposed the size as zero, both production predicates passed, and ZipFile.open() accepted the member before any read. Therefore malformed metadata reaches decompression despite exceeding MAX_ARCHIVE_MEMBER_BYTES.

    Deterministic regression: create an over-limit compressed member, patch its central size below the limit, instrument ZipFile.open() to fail if reached, and assert verification rejects the inconsistent declaration first.

  2. CONCERN β€” the per-member limit is not applied archive-wide.
    The total check covers every info at :188, but the per-member check occurs only inside the selected-member loop at :194-200. A probe with declared sizes [1, 1, 16777217] passed all current pre-open size checks because the oversized third entry remained below the 64 MiB aggregate limit.

    Deterministic regression: add a third entry declared as MAX_ARCHIVE_MEMBER_BYTES + 1, keep the total below MAX_ARCHIVE_EXPANDED_BYTES, and assert rejection before opening any member.

  3. PASS β€” upper-bound arithmetic does not wrap or admit negative values.
    The constants are 16 MiB and 64 MiB at :68-69; the > comparisons at :188 and :199 correctly allow equality and reject limit + 1. ...

gpt-5.6-sol · 2026-09-09 05:57:27 · ~567 tokens

Distillations (2)

Gen 0 2026-09-09 05:57:07 · 99 tokens

Date: Sep 9, 2026 * 🟑 (05:56) Repository status additionally showed modified files `pyproject.toml` and `uv.lock`, plus untracked files/directories `.lore.md`, `AGENTS.md`, `cases/review/oss-governance-adjudication-v1.inputs.json`, `cases/review/oss-governance-adjudication-v1/`, and `schema/governance-adjudication-v1.schema.json`.

Gen 0 2026-09-09 05:51:52 · 1295 tokens

Date: Sep 9, 2026 * πŸ”΄ [requested-security-audit] (05:38) User requested a fresh, minimal, read-only security audit for issue #4 in `/home/byk/Code/institutional-transition-lab`, limited exclusively to declared ZIP-size limit arithmetic. * πŸ”΄ (05:38) User stated this audit replaces a resource-accounting reviewer that returned empty twice. * πŸ”΄ [enforced-read-only-scope] (05:38) User instructed ne…