markdown · 3678 bytes Raw Blame History

Sprint 29: fortsh Link Audit

Prerequisites

Sprints 18–28 — every functional sprint, parity gate, performance tuning.

Goals

End-to-end link of fortsh under afs-ld. fortsh is ~57 KLoC Fortran 2018, 55 modules, heavy iso_c_binding, allocatable strings, derived types. Linking it is the first real-world stress test of everything before this sprint. Fix what breaks. No excuses.

Deliverables

1. fortsh build pipeline under afs-ld

cd fortsh
AFS_LD=1 armfortas --std=f2018 -O2 <all sources> -o fortsh

Expected:

  • Build succeeds.
  • ./fortsh --version prints the expected version string.
  • Interactive mode starts and reads a line.
  • ./fortsh -c "echo hello" prints "hello".

2. Failure taxonomy

Anticipated categories (adjust during sprint based on what actually breaks):

  • Symbol resolution: missing runtime symbols, weak-coalesce wrong winner, common-size mismatches.
  • Relocation math: PAGE21/PAGEOFF12 miscomputation on specific offsets, SUBTRACTOR pair issues in eh_frame.
  • TLV: thread-local I/O state failing at runtime.
  • Unwind: backtrace on crash produces garbage.
  • Dead-strip: functions stripped that were live (or live that should have been stripped).
  • Chained fixups: a chain crossing a page boundary or containing a bad next offset.
  • Code signature: kernel-kill on exec.

Each class has a known file/function starting point for triage from earlier sprints.

3. Audit process

Same rules as armfortas audits (armfortas/CLAUDE.md):

  • Assume nothing works until proven otherwise. Every subsystem gets exercised by some fortsh code path.
  • Stubs and placeholders are synonyms for broken. If fortsh passes a case only because of a hand-patched workaround, the sprint isn't done.
  • Wrong output is worse than crashes. A fortsh that "runs" but produces wrong answers is a critical failure.
  • Don't soften findings. "Major" = wrong answers. "Critical" = silent corruption.
  • Fix now unless it genuinely requires a later sprint.

Every bug becomes a regression test in tests/parity_corpus/fortsh_*/.

4. Runtime behavior matrix

Curated list of fortsh scenarios run under the afs-ld-linked binary:

  • Interactive echo, cat, ls (builtins).
  • Pipe: echo hello | cat.
  • Redirect: echo hello > /tmp/f.
  • Variables: x=1; echo $x.
  • Scripts: ./fortsh script.fsh.
  • Error paths: nonexistent_command returns non-zero.
  • iso_c_binding calls into libc from Fortran.
  • Allocatable string assignment: s = s // "more".
  • Derived-type shell_state_t access.

Every item green, or the sprint isn't done.

5. Differential vs system-ld-linked fortsh

Same fortsh source, linked by both. Runtime behavior must match for every scenario in §4. Binary size within 5%. Load-command shape equivalent. Output byte-by-byte for the parts our Sprint 27 rules cover.

6. Perf check

Link time for fortsh under afs-ld is within Sprint 28's 2× budget.

7. Audit report

.docs/audits/sprint29_fortsh.md (or wherever the project convention puts audit reports, parallel to armfortas's audit structure): a brutally honest writeup of what worked, what broke, what was fixed, what remains. No soft-pedaling.

Testing Strategy

  • Full fortsh test suite executed under both linker paths.
  • Each scenario in §4 scripted as a parity test.
  • Perf budget asserted.
  • Memory usage at link time within reason (< 1 GiB on fortsh).

Definition of Done

  • fortsh links under afs-ld.
  • Every scenario in §4 passes.
  • All fortsh integration tests pass.
  • Differential with ld-linked fortsh matches on every runtime scenario.
  • Audit report filed; no open critical items.
View source
1 # Sprint 29: fortsh Link Audit
2
3 ## Prerequisites
4 Sprints 18–28 — every functional sprint, parity gate, performance tuning.
5
6 ## Goals
7 End-to-end link of fortsh under afs-ld. fortsh is ~57 KLoC Fortran 2018, 55 modules, heavy `iso_c_binding`, allocatable strings, derived types. Linking it is the first real-world stress test of everything before this sprint. Fix what breaks. No excuses.
8
9 ## Deliverables
10
11 ### 1. fortsh build pipeline under afs-ld
12
13 ```
14 cd fortsh
15 AFS_LD=1 armfortas --std=f2018 -O2 <all sources> -o fortsh
16 ```
17
18 Expected:
19 - Build succeeds.
20 - `./fortsh --version` prints the expected version string.
21 - Interactive mode starts and reads a line.
22 - `./fortsh -c "echo hello"` prints "hello".
23
24 ### 2. Failure taxonomy
25
26 Anticipated categories (adjust during sprint based on what actually breaks):
27
28 - **Symbol resolution**: missing runtime symbols, weak-coalesce wrong winner, common-size mismatches.
29 - **Relocation math**: PAGE21/PAGEOFF12 miscomputation on specific offsets, SUBTRACTOR pair issues in eh_frame.
30 - **TLV**: thread-local I/O state failing at runtime.
31 - **Unwind**: backtrace on crash produces garbage.
32 - **Dead-strip**: functions stripped that were live (or live that should have been stripped).
33 - **Chained fixups**: a chain crossing a page boundary or containing a bad `next` offset.
34 - **Code signature**: kernel-kill on exec.
35
36 Each class has a known file/function starting point for triage from earlier sprints.
37
38 ### 3. Audit process
39
40 Same rules as armfortas audits (`armfortas/CLAUDE.md`):
41
42 - **Assume nothing works until proven otherwise.** Every subsystem gets exercised by some fortsh code path.
43 - **Stubs and placeholders are synonyms for broken.** If fortsh passes a case only because of a hand-patched workaround, the sprint isn't done.
44 - **Wrong output is worse than crashes.** A fortsh that "runs" but produces wrong answers is a critical failure.
45 - **Don't soften findings.** "Major" = wrong answers. "Critical" = silent corruption.
46 - **Fix now unless it genuinely requires a later sprint.**
47
48 Every bug becomes a regression test in `tests/parity_corpus/fortsh_*/`.
49
50 ### 4. Runtime behavior matrix
51
52 Curated list of fortsh scenarios run under the afs-ld-linked binary:
53
54 - Interactive `echo`, `cat`, `ls` (builtins).
55 - Pipe: `echo hello | cat`.
56 - Redirect: `echo hello > /tmp/f`.
57 - Variables: `x=1; echo $x`.
58 - Scripts: `./fortsh script.fsh`.
59 - Error paths: `nonexistent_command` returns non-zero.
60 - `iso_c_binding` calls into libc from Fortran.
61 - Allocatable string assignment: `s = s // "more"`.
62 - Derived-type shell_state_t access.
63
64 Every item green, or the sprint isn't done.
65
66 ### 5. Differential vs system-ld-linked fortsh
67
68 Same fortsh source, linked by both. Runtime behavior **must** match for every scenario in §4. Binary size within 5%. Load-command shape equivalent. Output byte-by-byte for the parts our Sprint 27 rules cover.
69
70 ### 6. Perf check
71
72 Link time for fortsh under afs-ld is within Sprint 28's 2× budget.
73
74 ### 7. Audit report
75
76 `.docs/audits/sprint29_fortsh.md` (or wherever the project convention puts audit reports, parallel to armfortas's audit structure): a brutally honest writeup of what worked, what broke, what was fixed, what remains. No soft-pedaling.
77
78 ## Testing Strategy
79
80 - Full fortsh test suite executed under both linker paths.
81 - Each scenario in §4 scripted as a parity test.
82 - Perf budget asserted.
83 - Memory usage at link time within reason (< 1 GiB on fortsh).
84
85 ## Definition of Done
86
87 - fortsh links under afs-ld.
88 - Every scenario in §4 passes.
89 - All fortsh integration tests pass.
90 - Differential with ld-linked fortsh matches on every runtime scenario.
91 - Audit report filed; no open critical items.