See also the page on certificate headers; app headers follow the same general format.
In the past, people liked to treat application headers as structs with fixed positions for everything. This is wrong. An application header is composed of variable-length fields. A valid application header must: Start with a master field ([]), end with a final field (807), contain a name field (804), a key ID field (801), a page count (808), and a date stamp field (032+090) followed by a date stamp signature field (020). Aside from the opening field being first, closing field being last, and dates stamp signature following the date stamp, those fields can be in any order. You may also specify a build (803) and revision (802) and disable the TI splash screen (809). There's also support for some other stuff, but it is all optional.
In theory, it is legal to specify the master field as 800D xxxx if the application is less than 64 K in size. However, rabbitsign won't sign it.
The name field can be less than 8 bytes, so you do not have to pad app names out to 8 bytes. You can also specify an app name greater than 8 bytes, but the calculator will ignore everything past the 8th byte.
The date stamp signature never actually gets checked, so you can put garbage there. But it gets better! You can also just specify the date stamp signature as having zero length. You can also pull a similar stunt with the date stamp itself.
The final field is usually written as 807F00000000. That four byte length field is ignored, so you can just put 8070 instead.
People like to pad the application header until it is 128 bytes in size. That is not necessary. Execution starts after the app header.
; Minimal application. This application is just 31 bytes! And takes up 16 K of archive space! ; Master Field .db 80h, 0Fh, 0, 0, 0, 0 ; Name. Note that the name field reads 80 43 because the name specified here is 3 characters long. .db 80h, 43h, "nop" ; Disable TI splash screen. .db 80h, 90h ; Pages .db 80h, 81h, 1 ; Signing Key ID .db 80h, 12h, 1, 4 ; or 15 for the TI-84+CSE ; Date stamp. Apparently, the calculator doesn't mind if you put ; nothing in this. .db 03h, 22h, 09h, 00h ; Date stamp signature. Since nothing ever checks this, there's no ; reason ever to update it. Or even have data in it. .db 02h, 00 ; Final field .db 80h, 70h ; No need for padding here. The OS will just start execution here. b_call(_JForceCmdNoChar)