markdown · 10782 bytes Raw Blame History

Sprint 0-9 Closeout Checklist

Concrete closeout checklist based on the current codebase audit.

Current conclusion: we are not ready to honestly declare Sprint 10 complete-in-practice yet. The main blockers are:

  • Sprint 0's tolerated-diff categories are still deferred until afs-ld can emit real linked output for Mach-O-to-Mach-O differential checks.

Sprint 10 Gate

Do not declare "we are on Sprint 10" until all of these are true:

  • Sprint 9 reloc referents are remapped to atom-aware forms.
  • Sprint 8 resolution orchestration exists as a real callable stage, not just loose helper APIs.
  • cargo test -p afs-ld is green after the closeout work.
  • cargo clippy -p afs-ld --all-targets -- -D warnings is green after the closeout work.
  • README.md and sprint docs no longer materially misstate the current state of the crate.
  • Close Sprint 9 reloc-to-atom remap first.
  • Close Sprint 8 resolution orchestration and option coverage second.
  • Close Sprint 6 TBD/SDK search gaps third.
  • Close Sprint 4 nested archive support fourth.
  • Finish the deferred Sprint 0 differential-harness tolerance work once afs-ld can emit real output.

Cross-Sprint Exit Criteria

  • Every closeout chunk lands with tests.
  • Every bug fix or behavioral gap gets a regression test.
  • No newly-discovered roadmap/code mismatch is left undocumented.
  • Any user-facing diagnostic we touch stays deterministic and testable.

Sprint 0

Status: closed

Validated:

  • afs-ld exists as its own git submodule in the parent workspace.
  • Parent Cargo.toml includes afs-ld as a workspace member.
  • CLAUDE.md, README.md, crate wiring, and test harness scaffolding exist.
  • Reference repos are present under parent .refs/ (ld64, mold, lld).
  • tests/reader_empty.rs enforces the empty-invocation CLI contract.
  • tests/diff_harness_sanity.rs and tests/diff_harness_finds_critical.rs exist and pass.
  • cargo clippy -p afs-ld --all-targets -- -D warnings is currently clean.

Remaining closeout work:

  • Explicitly downscope Sprint 0 docs so the current diff harness is described as synthetic until end-to-end linking exists.
  • Add tolerated-diff categories once real Mach-O-to-Mach-O comparisons exist.

Sprint 1

Status: closed

Validated:

  • Mach-O constants are duplicated locally in src/macho/constants.rs.
  • MachHeader64 parsing exists and rejects malformed headers.
  • Load-command dispatch exists and preserves unknown commands as raw bytes.
  • Segment and section-header metadata parsing exists.
  • LC_BUILD_VERSION and LC_LINKER_OPTIMIZATION_HINT decoding exists.
  • --dump exists through src/dump.rs and src/main.rs.
  • Corpus round-trip tests pass in tests/reader_corpus_round_trip.rs.

Remaining closeout work:

  • Add an otool -lV parity test for dumper output shape across the corpus.
  • Add a panic-focused malformed-input stress pass beyond the current unit tests so the "no panics on malformed input" claim is defensible.

Sprint 2

Status: closed

Validated:

  • Section classification exists in src/section.rs.
  • InputSection carries section data and raw relocation bytes.
  • RawNlist / InputSymbol parsing and classification exist in src/symbol.rs.
  • Common symbols, weak flags, private externs, and indirect aliases are surfaced.
  • StringTable exists and handles suffix-dedup overlaps.
  • DysymtabCmd is parsed and exposed through ObjectFile.
  • ObjectFile integrates header, commands, sections, symbols, strings, and dysymtab.

Remaining closeout work:

  • Add nm -a parity tests for symbol view and classification.
  • Add otool -r parity checks for relocation-offset surfaces promised by Sprint 2, with section/load-command parity covered by the Sprint 1 otool -lV gate.
  • Add stronger malformed-symbol / malformed-string-table stress coverage if we want the "never panics" bar to be explicit.

Sprint 3

Status: closed enough for current closeout

Validated:

  • ARM64 relocation constants exist.
  • Raw relocation parsing and writing exist.
  • Fused Reloc form exists.
  • ADDEND and SUBTRACTOR + UNSIGNED pairing is fused in parse_relocs.
  • Validation logic exists in validate_relocs.
  • Write-side round-trip support exists.
  • Unit coverage is broad and current corpus relocation round-trips pass.

Remaining closeout work:

  • No audit-blocking work found for Sprint 3.

Sprint 4

Status: closed

Validated:

  • BSD, SysV, and GNU-thin archive flavors are recognized.
  • Archive headers and name decoding are implemented.
  • Symbol-index parsing exists for BSD and SysV archives.
  • Lazy member fetch exists via fetch_object_defining.
  • libarmfortas_rt.a is exercised by tests/archive_runtime.rs.
  • Archive dump mode exists via --dump-archive.

Remaining closeout work:

  • Implement one-level nested archive support (.a member inside .a) and preserve provenance for diagnostics.
  • Formally treat resolve::force_load_archive / force_load_all as the Sprint 4 completion surface and document that surface instead of adding a parallel archive-only helper.
  • Add ar -t shape/parity coverage for --dump-archive.

Sprint 5

Status: partially closed

Validated:

  • DylibFile exists and parses binary MH_DYLIB.
  • LC_ID_DYLIB, dependency dylib commands, ordinals, and rpaths are decoded.
  • Export trie decoding exists with cycle/depth protection.
  • Real clang-built dylib coverage exists in tests/dylib_integration.rs.
  • Dylib dump mode exists via --dump-dylib.

Remaining closeout work:

  • Prove recursive re-export / umbrella lookup behavior with a focused test, not just dependency collection.
  • Confirm the public dylib surface matches what Sprint 5 intended for re-exported symbols, not only direct exports.

Sprint 6

Status: closed

Validated:

  • The custom YAML subset parser exists in src/macho/tbd_yaml.rs.
  • TBD schema decoding exists in src/macho/tbd.rs.
  • DylibFile::from_tbd exists and materializes TBDs into the same linker-facing surface.
  • Real libSystem.tbd smoke/integration coverage exists in tests/tbd_smoke.rs and tests/tbd_integration.rs.
  • TBD dump mode exists via --dump-tbd.

Remaining closeout work:

  • Implement SDK -syslibroot library search helpers for .tbd / .dylib.
  • Implement framework search helpers promised by Sprint 6.
  • Make target filtering fail loudly when the requested target is not exported, instead of only materializing matching targets when the caller already knows one exists.
  • No further audit-blocking work found for Sprint 6 in the current helper/test surface.

Sprint 7

Status: closed

Validated:

  • Symbol sum type exists with the planned major variants.
  • StringInterner, opaque ids, and SymbolTable exist.
  • The insertion matrix is heavily unit-tested.
  • Weak/strong/common coalescing behavior is covered in unit tests.
  • Alias-cycle detection and chain resolution exist.
  • Transition logging exists.

Remaining closeout work:

  • Add the differential weak-coalescing / duplicate-behavior coverage against system ld that Sprint 7 originally called for.

Sprint 8

Status: closed

Validated:

  • Archive seeding, object seeding, and dylib seeding exist.
  • Fixed-point archive fetch draining exists.
  • force_load_archive and force_load_all helpers exist in src/resolve.rs.
  • Undefined classification exists for Error, Warning, Suppress, and DynamicLookup.
  • Did-you-mean support exists.
  • Duplicate-symbol and undefined-symbol formatting helpers exist.
  • Real integration coverage exists for archive pull plus unresolved-symbol reporting.

Remaining closeout work:

  • Add a real orchestration entrypoint for resolution (seed -> optional force load -> drain -> classify) that can be called as a coherent stage.
  • Add option/state plumbing for all_load, force_load, and undefined treatment so resolution is not just a bag of helper APIs.
  • Add an archive order-sensitivity test.
  • Add dedicated tests for force_load_archive and force_load_all.
  • Add dedicated tests for UndefinedTreatment::Warning, Suppress, and DynamicLookup.
  • Add a dedicated test that unresolved weak refs stay accepted regardless of treatment.
  • Tighten diagnostics toward the Sprint 8 format by carrying section/offset provenance and aggregate repeated relocation sites when available.

Sprint 9

Status: closed

Validated:

  • Atom model and atom table exist.
  • Section splitting at symbol boundaries exists.
  • .alt_entry folding exists.
  • CString atom splitting exists and is integration-tested.
  • Compact-unwind atom splitting and parent_of wiring exist.
  • Backpatching of Symbol::Defined { atom } exists.
  • N_NO_DEAD_STRIP and weak-def flags are propagated into atom flags.
  • Embedded payload addends on symbol-based data relocs are folded into local atom offsets or preserved on external refs.

Remaining closeout work:

  • Remap relocations from raw section/symbol referents into atom-aware referents.
  • Add atom-local relocation storage or an equivalent per-atom relocation view.
  • Ensure same-object references point at target atoms, not raw section offsets.
  • Add a focused integration test proving a local branch or data reference resolves to the callee/target atom.
  • Add a boundary-crossing reloc diagnostic test.
  • Confirm no raw section-relative relocation state leaks into Sprint 10 inputs.
  • No further audit-blocking work found for Sprint 9 in the current corpus and targeted local-addend probes.

Documentation Closeout

  • Update README.md so it no longer says the crate is only Sprint 0 scaffolding.
  • Refresh sprint docs whose deliverables have been implemented under a different surface than originally planned.
  • Keep CLAUDE.md as the authority for discipline, but make user-facing docs match the actual code.

Verification Commands

  • cargo test -p afs-ld
  • cargo clippy -p afs-ld --all-targets -- -D warnings
  • Focused xcrun-backed checks when touching reader/resolve/atom/TBD/dylib paths:
    • cargo test -p afs-ld --test reader_corpus_round_trip -- --nocapture
    • cargo test -p afs-ld --test resolve_integration -- --nocapture
    • cargo test -p afs-ld --test atom_integration -- --nocapture
    • cargo test -p afs-ld --test dylib_integration -- --nocapture
    • cargo test -p afs-ld --test tbd_integration -- --nocapture
View source
1 # Sprint 0-9 Closeout Checklist
2
3 Concrete closeout checklist based on the current codebase audit.
4
5 Current conclusion: we are not ready to honestly declare Sprint 10 complete-in-practice yet.
6 The main blockers are:
7
8 - Sprint 0's tolerated-diff categories are still deferred until afs-ld can emit real linked output for Mach-O-to-Mach-O differential checks.
9
10 ## Sprint 10 Gate
11
12 Do not declare "we are on Sprint 10" until all of these are true:
13
14 - [x] Sprint 9 reloc referents are remapped to atom-aware forms.
15 - [x] Sprint 8 resolution orchestration exists as a real callable stage, not just loose helper APIs.
16 - [x] `cargo test -p afs-ld` is green after the closeout work.
17 - [x] `cargo clippy -p afs-ld --all-targets -- -D warnings` is green after the closeout work.
18 - [x] `README.md` and sprint docs no longer materially misstate the current state of the crate.
19
20 ## Recommended Order
21
22 - [x] Close Sprint 9 reloc-to-atom remap first.
23 - [x] Close Sprint 8 resolution orchestration and option coverage second.
24 - [x] Close Sprint 6 TBD/SDK search gaps third.
25 - [x] Close Sprint 4 nested archive support fourth.
26 - [ ] Finish the deferred Sprint 0 differential-harness tolerance work once afs-ld can emit real output.
27
28 ## Cross-Sprint Exit Criteria
29
30 - [ ] Every closeout chunk lands with tests.
31 - [ ] Every bug fix or behavioral gap gets a regression test.
32 - [ ] No newly-discovered roadmap/code mismatch is left undocumented.
33 - [ ] Any user-facing diagnostic we touch stays deterministic and testable.
34
35 ## Sprint 0
36
37 Status: closed
38
39 Validated:
40
41 - [x] `afs-ld` exists as its own git submodule in the parent workspace.
42 - [x] Parent `Cargo.toml` includes `afs-ld` as a workspace member.
43 - [x] `CLAUDE.md`, `README.md`, crate wiring, and test harness scaffolding exist.
44 - [x] Reference repos are present under parent `.refs/` (`ld64`, `mold`, `lld`).
45 - [x] `tests/reader_empty.rs` enforces the empty-invocation CLI contract.
46 - [x] `tests/diff_harness_sanity.rs` and `tests/diff_harness_finds_critical.rs` exist and pass.
47 - [x] `cargo clippy -p afs-ld --all-targets -- -D warnings` is currently clean.
48
49 Remaining closeout work:
50
51 - [x] Explicitly downscope Sprint 0 docs so the current diff harness is described as synthetic until end-to-end linking exists.
52 - [ ] Add tolerated-diff categories once real Mach-O-to-Mach-O comparisons exist.
53
54 ## Sprint 1
55
56 Status: closed
57
58 Validated:
59
60 - [x] Mach-O constants are duplicated locally in `src/macho/constants.rs`.
61 - [x] `MachHeader64` parsing exists and rejects malformed headers.
62 - [x] Load-command dispatch exists and preserves unknown commands as raw bytes.
63 - [x] Segment and section-header metadata parsing exists.
64 - [x] `LC_BUILD_VERSION` and `LC_LINKER_OPTIMIZATION_HINT` decoding exists.
65 - [x] `--dump` exists through `src/dump.rs` and `src/main.rs`.
66 - [x] Corpus round-trip tests pass in `tests/reader_corpus_round_trip.rs`.
67
68 Remaining closeout work:
69
70 - [x] Add an `otool -lV` parity test for dumper output shape across the corpus.
71 - [x] Add a panic-focused malformed-input stress pass beyond the current unit tests so the "no panics on malformed input" claim is defensible.
72
73 ## Sprint 2
74
75 Status: closed
76
77 Validated:
78
79 - [x] Section classification exists in `src/section.rs`.
80 - [x] `InputSection` carries section data and raw relocation bytes.
81 - [x] `RawNlist` / `InputSymbol` parsing and classification exist in `src/symbol.rs`.
82 - [x] Common symbols, weak flags, private externs, and indirect aliases are surfaced.
83 - [x] `StringTable` exists and handles suffix-dedup overlaps.
84 - [x] `DysymtabCmd` is parsed and exposed through `ObjectFile`.
85 - [x] `ObjectFile` integrates header, commands, sections, symbols, strings, and dysymtab.
86
87 Remaining closeout work:
88
89 - [x] Add `nm -a` parity tests for symbol view and classification.
90 - [x] Add `otool -r` parity checks for relocation-offset surfaces promised by Sprint 2, with section/load-command parity covered by the Sprint 1 `otool -lV` gate.
91 - [x] Add stronger malformed-symbol / malformed-string-table stress coverage if we want the "never panics" bar to be explicit.
92
93 ## Sprint 3
94
95 Status: closed enough for current closeout
96
97 Validated:
98
99 - [x] ARM64 relocation constants exist.
100 - [x] Raw relocation parsing and writing exist.
101 - [x] Fused `Reloc` form exists.
102 - [x] `ADDEND` and `SUBTRACTOR + UNSIGNED` pairing is fused in `parse_relocs`.
103 - [x] Validation logic exists in `validate_relocs`.
104 - [x] Write-side round-trip support exists.
105 - [x] Unit coverage is broad and current corpus relocation round-trips pass.
106
107 Remaining closeout work:
108
109 - [x] No audit-blocking work found for Sprint 3.
110
111 ## Sprint 4
112
113 Status: closed
114
115 Validated:
116
117 - [x] BSD, SysV, and GNU-thin archive flavors are recognized.
118 - [x] Archive headers and name decoding are implemented.
119 - [x] Symbol-index parsing exists for BSD and SysV archives.
120 - [x] Lazy member fetch exists via `fetch_object_defining`.
121 - [x] `libarmfortas_rt.a` is exercised by `tests/archive_runtime.rs`.
122 - [x] Archive dump mode exists via `--dump-archive`.
123
124 Remaining closeout work:
125
126 - [x] Implement one-level nested archive support (`.a` member inside `.a`) and preserve provenance for diagnostics.
127 - [x] Formally treat `resolve::force_load_archive` / `force_load_all` as the Sprint 4 completion surface and document that surface instead of adding a parallel archive-only helper.
128 - [x] Add `ar -t` shape/parity coverage for `--dump-archive`.
129
130 ## Sprint 5
131
132 Status: partially closed
133
134 Validated:
135
136 - [x] `DylibFile` exists and parses binary `MH_DYLIB`.
137 - [x] `LC_ID_DYLIB`, dependency dylib commands, ordinals, and rpaths are decoded.
138 - [x] Export trie decoding exists with cycle/depth protection.
139 - [x] Real clang-built dylib coverage exists in `tests/dylib_integration.rs`.
140 - [x] Dylib dump mode exists via `--dump-dylib`.
141
142 Remaining closeout work:
143
144 - [ ] Prove recursive re-export / umbrella lookup behavior with a focused test, not just dependency collection.
145 - [ ] Confirm the public dylib surface matches what Sprint 5 intended for re-exported symbols, not only direct exports.
146
147 ## Sprint 6
148
149 Status: closed
150
151 Validated:
152
153 - [x] The custom YAML subset parser exists in `src/macho/tbd_yaml.rs`.
154 - [x] TBD schema decoding exists in `src/macho/tbd.rs`.
155 - [x] `DylibFile::from_tbd` exists and materializes TBDs into the same linker-facing surface.
156 - [x] Real `libSystem.tbd` smoke/integration coverage exists in `tests/tbd_smoke.rs` and `tests/tbd_integration.rs`.
157 - [x] TBD dump mode exists via `--dump-tbd`.
158
159 Remaining closeout work:
160
161 - [x] Implement SDK `-syslibroot` library search helpers for `.tbd` / `.dylib`.
162 - [x] Implement framework search helpers promised by Sprint 6.
163 - [x] Make target filtering fail loudly when the requested target is not exported, instead of only materializing matching targets when the caller already knows one exists.
164 - [x] No further audit-blocking work found for Sprint 6 in the current helper/test surface.
165
166 ## Sprint 7
167
168 Status: closed
169
170 Validated:
171
172 - [x] `Symbol` sum type exists with the planned major variants.
173 - [x] `StringInterner`, opaque ids, and `SymbolTable` exist.
174 - [x] The insertion matrix is heavily unit-tested.
175 - [x] Weak/strong/common coalescing behavior is covered in unit tests.
176 - [x] Alias-cycle detection and chain resolution exist.
177 - [x] Transition logging exists.
178
179 Remaining closeout work:
180
181 - [ ] Add the differential weak-coalescing / duplicate-behavior coverage against system `ld` that Sprint 7 originally called for.
182
183 ## Sprint 8
184
185 Status: closed
186
187 Validated:
188
189 - [x] Archive seeding, object seeding, and dylib seeding exist.
190 - [x] Fixed-point archive fetch draining exists.
191 - [x] `force_load_archive` and `force_load_all` helpers exist in `src/resolve.rs`.
192 - [x] Undefined classification exists for `Error`, `Warning`, `Suppress`, and `DynamicLookup`.
193 - [x] Did-you-mean support exists.
194 - [x] Duplicate-symbol and undefined-symbol formatting helpers exist.
195 - [x] Real integration coverage exists for archive pull plus unresolved-symbol reporting.
196
197 Remaining closeout work:
198
199 - [x] Add a real orchestration entrypoint for resolution (`seed -> optional force load -> drain -> classify`) that can be called as a coherent stage.
200 - [x] Add option/state plumbing for `all_load`, `force_load`, and undefined treatment so resolution is not just a bag of helper APIs.
201 - [x] Add an archive order-sensitivity test.
202 - [x] Add dedicated tests for `force_load_archive` and `force_load_all`.
203 - [x] Add dedicated tests for `UndefinedTreatment::Warning`, `Suppress`, and `DynamicLookup`.
204 - [x] Add a dedicated test that unresolved weak refs stay accepted regardless of treatment.
205 - [x] Tighten diagnostics toward the Sprint 8 format by carrying section/offset provenance and aggregate repeated relocation sites when available.
206
207 ## Sprint 9
208
209 Status: closed
210
211 Validated:
212
213 - [x] Atom model and atom table exist.
214 - [x] Section splitting at symbol boundaries exists.
215 - [x] `.alt_entry` folding exists.
216 - [x] CString atom splitting exists and is integration-tested.
217 - [x] Compact-unwind atom splitting and `parent_of` wiring exist.
218 - [x] Backpatching of `Symbol::Defined { atom }` exists.
219 - [x] `N_NO_DEAD_STRIP` and weak-def flags are propagated into atom flags.
220 - [x] Embedded payload addends on symbol-based data relocs are folded into local atom offsets or preserved on external refs.
221
222 Remaining closeout work:
223
224 - [x] Remap relocations from raw section/symbol referents into atom-aware referents.
225 - [x] Add atom-local relocation storage or an equivalent per-atom relocation view.
226 - [x] Ensure same-object references point at target atoms, not raw section offsets.
227 - [x] Add a focused integration test proving a local branch or data reference resolves to the callee/target atom.
228 - [x] Add a boundary-crossing reloc diagnostic test.
229 - [x] Confirm no raw section-relative relocation state leaks into Sprint 10 inputs.
230 - [x] No further audit-blocking work found for Sprint 9 in the current corpus and targeted local-addend probes.
231
232 ## Documentation Closeout
233
234 - [x] Update `README.md` so it no longer says the crate is only Sprint 0 scaffolding.
235 - [x] Refresh sprint docs whose deliverables have been implemented under a different surface than originally planned.
236 - [x] Keep `CLAUDE.md` as the authority for discipline, but make user-facing docs match the actual code.
237
238 ## Verification Commands
239
240 - [x] `cargo test -p afs-ld`
241 - [x] `cargo clippy -p afs-ld --all-targets -- -D warnings`
242 - [ ] Focused xcrun-backed checks when touching reader/resolve/atom/TBD/dylib paths:
243 - [x] `cargo test -p afs-ld --test reader_corpus_round_trip -- --nocapture`
244 - [x] `cargo test -p afs-ld --test resolve_integration -- --nocapture`
245 - [x] `cargo test -p afs-ld --test atom_integration -- --nocapture`
246 - [x] `cargo test -p afs-ld --test dylib_integration -- --nocapture`
247 - [x] `cargo test -p afs-ld --test tbd_integration -- --nocapture`