Skip to content
Merged
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
19 changes: 8 additions & 11 deletions docs/CODEBASE_MAP.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
last_mapped: 2026-04-01T00:00:00Z
last_mapped: 2026-04-12T00:00:00Z
total_files: 233
total_tokens: ~180000
---

# Codebase Map

> Auto-generated by Cartographer. Last mapped: 2026-04-01
> Auto-generated by Cartographer. Last mapped: 2026-04-12

## System Overview

Expand Down Expand Up @@ -106,6 +106,7 @@ sequenceDiagram

```
spawn.build/
├── .github/workflows/ # CI (main-pull-request.yml), snapshot, and release workflows
├── config/checkstyle/ # Checkstyle rules (tabs, star imports, finals, braces)
├── docs/ # Architecture documentation (this file)
├── spawn-option/ # JPMS: build.spawn.option — shared option types
Expand Down Expand Up @@ -211,7 +212,7 @@ spawn.build/
| `option/ModulePath.java` | `-p`; modular JDKs only; `inherited()` reads `jdk.module.path` |
| `option/SystemProperty.java` | `-Dkey[=value]`; `MappedOption<String>`; expression-resolvable |
| `option/JDKAgent.java` | `-javaagent:path[=args]`; `CollectedOption<List>` |
| `option/Headless.java` | Enum; `ENABLED` is `@Default`; `DISABLED` emits no tokens |
| `option/Headless.java` | Enum; `ENABLED` (`@Default`) adds `-Djava.awt.headless=true`; `DISABLED` emits no tokens |

**SpawnAgent two-way communication flow:**
```
Expand All @@ -235,8 +236,7 @@ Server (listens on spawn:// URI)
```

**Known bugs in `spawn-jdk`:**
- `SpawnAgent.parseArguments` splits on `"="` without limit — token values containing `=` (e.g. Base64) are silently dropped. Fix: `s.split("=", 2)`. Documented in `SpawnAgentArgumentParsingTests`.
- `PatchModule.detect()` has the same split bug for `--patch-module=module=path` args.
- `PatchModule.detect()` has a split-on-`=` bug for `--patch-module=module=path` args (no limit — third segment dropped).
- `AbstractHeapSize`: memory unit suffix derived from first letter of enum name — adding a misnamed `MemorySize` enum would produce wrong JVM flag silently.

---
Expand Down Expand Up @@ -270,7 +270,7 @@ Server (listens on spawn:// URI)
| File | Purpose |
|------|---------|
| `JDKDetector.java` | Interface + static factories; `of(Path)` reads `release` file (no subprocess); `stream()` via `ServiceLoader` |
| `JDKHomeBasedPatternDetector.java` | `@AutoService` impl; reads `java.home.properties` OS-specific globs; caches result in `AtomicReference` |
| `JDKHomeBasedPatternDetector.java` | Native JPMS service impl (registered via `module-info.java` `provides…with`); reads `java.home.properties` OS-specific globs; caches result in `AtomicReference` |
| `LocalJDKLauncher.java` | Builds `java` command line including SpawnAgent injection; discovers or creates `spawn-agent.jar` |
| `java.home.properties` | OS-keyed glob patterns: `mac@*`, `unix@*` entries for JDK installation directories |
| `META-INF/build.spawn.platform.local.LocalMachine` | Registry: `JDKApplication=LocalJDKLauncher` |
Expand All @@ -284,8 +284,6 @@ Server (listens on spawn:// URI)
- **Linux (unix):** `/usr/lib/jvm/java-*`, `jdk-*`, `zulu*`; `/usr/local/*jdk*`; SDKMAN; Linuxbrew (`jdk-*` and `zulu*` added in commit `ebee957`)
- **Windows:** No patterns — detection only works via `JDKDetector.current()` / `detectDefault()`

**Known log bug in `JDKHomeBasedPatternDetector`:** `{0}` used twice in "Skipping path" message instead of `{0}` and `{1}` — pattern value never appears. Documented in `JDKHomeBasedPatternDetectorLogTests`.

**`LocalJDKLauncher` command structure:**
```
"<jdk-home>/bin/java"
Expand Down Expand Up @@ -321,16 +319,15 @@ Server (listens on spawn:// URI)
|--------|------------------|-------|
| `ImageName` | (image reference) | Handles tags, SHA256 refs, registry prefixing |
| `ExposedPort` | `ExposedPorts` | Metadata only; use `PublishPort` for host mapping |
| `PublishPort` | `HostConfig.PortBindings` | **Bug:** multiple bindings for same key discarded |
| `PublishPort` | `HostConfig.PortBindings` | |
| `Bind` | `HostConfig.Binds` | **Bug:** `requireNonNull` checks wrong param name |
| `Command` | `Cmd` | Sets container CMD array |
| `ContainerName` | `?name=` query param | 409 if duplicate |
| `NetworkName` | `HostConfig.NetworkMode` | |
| `PublishAllPorts` | `HostConfig.PublishAllPorts` | `@Default ENABLED` |
| `KillSignal` | `signal` query param | Enum: `SIGKILL` (`@Default`), `SIGTERM`, `SIGQUIT`, `SIGHUP` |

**Known bugs in `spawn-docker`:**
- `PublishPort.configure`: checks `objectNode.get(key)` instead of `portBindings.get(key)` → all but last binding for a given port key silently discarded (`PublishPortTests` documents)
- `Images.build(DockerContextBuilder)` swallows `IOException` from context builder (`ImagesBuildTests` documents)
- `Bind`: `requireNonNull` for `internalPath` references `externalPath` param name (copy-paste; runtime behavior correct)

---
Expand Down
Loading