Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/courtlistener.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: CourtListener through ICU

on:
push:
branches:
- courtlistener-icu-foundation
pull_request:
workflow_dispatch:

jobs:
courtlistener:
runs-on: ubuntu-latest
steps:
- name: Checkout Idriç CLI
uses: actions/checkout@v4

- name: Checkout Idriç compiler
uses: actions/checkout@v4
with:
repository: isomorphisms/Idric
ref: 47557b43053c829d4f8aa1581007002b57f9c59f
path: .tools/Idric

- name: Checkout Idric-Net
uses: actions/checkout@v4
with:
repository: isomorphisms/Idric-Net
ref: 3e7643c8d8dd2a940d5b6dc96403ddae765402cd
path: .tools/Idric-Net

- name: Checkout ICU API-client boundary
uses: actions/checkout@v4
with:
repository: dilapidated-shed/icu
ref: 4ea624544d5b033bf83ab155e3783538e2ba1d58
path: .tools/icu

- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y chezscheme libssl-dev

- name: Build Idriç compiler
run: make -C .tools/Idric bootstrap SCHEME=scheme

- name: Install Idric-Net
env:
IDRIS2_PREFIX: ${{ github.workspace }}/.tools/Idric/bootstrap-build
run: |
cd .tools/Idric-Net
../Idric/build/exec/idris2 --install idric-net.ipkg

- name: Install contrib
env:
IDRIS2_PREFIX: ${{ github.workspace }}/.tools/Idric/bootstrap-build
run: |
cd .tools/Idric/libs/contrib
../../build/exec/idris2 --install contrib.ipkg

- name: Build ICU response adapter
env:
IDRIS2_PREFIX: ${{ github.workspace }}/.tools/Idric/bootstrap-build
run: |
make -C .tools/icu libicu_transport.so
sed -i \
's/^modules =.*/modules = Http, TransportModel, Transport, Ingestion/' \
.tools/icu/icu.ipkg
sed -i '/^main =/d; /^executable =/d' .tools/icu/icu.ipkg
cd .tools/icu
../Idric/build/exec/idris2 --install icu.ipkg
cd ../..
.tools/Idric/build/exec/idris2 -p icu \
test/courtlistener/IcuRunner.idric -o icu-courtlistener
test -x build/exec/icu-courtlistener

- name: Run deterministic and live receipts
env:
COURTLISTENER_LIVE: 1
ICU: ${{ github.workspace }}/build/exec/icu-courtlistener
IDRIC: ${{ github.workspace }}/.tools/Idric/build/exec/idris2
IDRIS2_PREFIX: ${{ github.workspace }}/.tools/Idric/bootstrap-build
LD_LIBRARY_PATH: ${{ github.workspace }}/.tools/icu
run: sh test/courtlistener/check
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
config/amazon-secret
.state/
.cache/
build/
1 change: 1 addition & 0 deletions CourtListener.idric
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
PREFIX ?= /usr/local
DESTDIR ?=
SHELL ?= /bin/sh
IDRIC ?= idris2

.PHONY: test install
.PHONY: test courtlistener courtlistener-check install

test:
bash test/az-test.sh
bash test/abe-test.sh

courtlistener:
$(IDRIC) --build courtlistener.ipkg

courtlistener-check:
sh test/courtlistener/check

install:
install -d "$(DESTDIR)$(PREFIX)/bin"
install -m 0755 bin/az "$(DESTDIR)$(PREFIX)/bin/az"
install -m 0755 bin/abe "$(DESTDIR)$(PREFIX)/bin/abe"
if test -x build/exec/edric; then \
install -m 0755 build/exec/edric "$(DESTDIR)$(PREFIX)/bin/edric"; \
fi
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,40 @@ This repository is the consolidation point for the CLI/API-access programs that
- `Reddit.idric` — Reddit Data API checkpoint, with a synthetic fixture and manual receipt.
- `Reuters.idric` — Reuters GraphQL checkpoint.
- `Wayback.idric` — Internet Archive Wayback/CDX checkpoint.
- `CourtListener.idric` — executable CourtListener v4 case-law search through ICU.

The top-level `.idric` files are symbolic links to the canonical sources under `checkpoints/`, so the important source is visible without digging through directories.
The top-level `.idric` files are symbolic links to their canonical sources, so the important source is visible without digging through directories.

Some Idriç clients intentionally contain named holes for compiler/library boundaries that are not implemented yet. Keep those boundaries visible; do not make a client appear green by silently substituting another HTTP implementation.

## CourtListener

Build and run the first legal-search command with:

```text
make courtlistener IDRIC=/opt/Idric/build/exec/idris2
edric courtlistener search "Brown v. Board of Education"
```

The installed ICU command owns HTTP and TLS. `ICU=/path/to/icu` selects it when
it is not on `PATH`; `COURTLISTENER_API_TOKEN` supplies optional token
authentication through ICU's checked header boundary. See
[`docs/courtlistener.md`](docs/courtlistener.md) for the exact ownership and
response contracts.

## Networking

Where these clients need networking, ICU/Idric-Net remains the intended transport boundary. ICU is deliberately **not** a Git submodule here and is not pinned by this repository.
Where these clients need networking, ICU/Idric-Net remains the intended transport boundary. ICU is deliberately **not** a Git submodule or pinned runtime dependency here. The CourtListener acceptance workflow pins a reviewed ICU revision only so its receipt is reproducible.

## Tests

`make test` runs the existing Amazon and AbeBooks smoke tests. Reddit has a separate manual compiler checkpoint at `checkpoints/reddit/check`; it is not part of `make test` while named Idriç holes remain.

See `PROVENANCE.md` for the source branches copied into this repository.

The CourtListener receipt is separate because it requires the Idriç compiler,
Idric-Net, contrib, and ICU:

```text
make courtlistener-check IDRIC=/opt/Idric/build/exec/idris2
```
9 changes: 9 additions & 0 deletions courtlistener.ipkg
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package courtlistener

version = 0.1.0
depends = contrib, idric_net
sourcedir = "src"

modules = CourtListener, Main
main = Main
executable = edric
53 changes: 53 additions & 0 deletions docs/courtlistener.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# CourtListener CLI boundary

The first command is:

```text
edric courtlistener search "Brown v. Board of Education"
```

The Idriç layer owns the command grammar, the `CourtListener_Query`, the typed
search request, the CourtListener JSON fields, and human-readable output. It
constructs the documented v4 case-law search request with `type=o`.

ICU owns HTTP, TLS, redirects, response capture, and transport outcomes. The
CLI invokes the installed ICU command through an escaped argument list. It
does not contain sockets, TLS, HTTP framing, curl, or a second native adapter.
The required ICU response boundary is the existing API-client work that:

- accepts checked `-H` request headers;
- writes the response body to stdout;
- exits `10` for a non-2xx response;
- uses its other nonzero outcomes for request/network/transport failures.

ICU remains a moving external runtime dependency rather than a submodule. The
acceptance workflow alone pins a reviewed ICU response-boundary revision so a
given receipt can be reproduced.

Set `ICU` to the ICU executable when it is not on `PATH`. If supplied,
`COURTLISTENER_API_TOKEN` becomes `Authorization: Token ...` at the ICU header
boundary. Tokens are never accepted as command arguments or stored here.

The initial query encoder deliberately refuses non-ASCII input until the Idriç
UTF-8 percent-encoding boundary is available. It does not send malformed text
or silently reinterpret it.

The response decoder preserves fields that are present in the v4 opinion-search
response: `caseName`, `court`, `dateFiled`, `citation`, and `absolute_url`.
`court` and `dateFiled` remain optional; `citation` remains plural.

## Next records

`search` is the current resource. The next obvious endpoint is `dockets`,
followed by `docket-entries`. Likely later targets are `recap-documents`,
`parties`, `attorneys`, `clusters`, `opinions`, `opinions-cited`,
`citation-lookup`, `people`, `positions`, and `educations`.

These records can eventually support:

```text
school → person → position → court → case → docket entry → attorney → party
case → cites → case
```

This repository does not build that graph yet.
Loading
Loading