Joel, here's more feedback on what you already have in there.
In figure 8.4, the statement;
select define_function_args(samplenote__new,'note_id,title,creation_date,creation_user,creation_ip,context_id');
should read:
select define_function_args(samplenote__new,'note_id,object_type;samplenote,title,creation_date,creation_user,creation_ip,context_id');
(note the added "object_type;samplenote")
This parameter should only be in the "*__new" functions. I haven't studied the code closely and recently enough to be able to explain why it is needed, but I do know from own experience that this is the case.
ad_table:
I found an undocumented feature by looking through the code that may be worth mentioning. $orderby can be made to sort descending by default as opposed to ascending by suffixing the key with a "*" .... So if one says "{orderby:optional {title*}}" the titles (say) will be sorted in the reverse order compared to your example.
Regarding the add/edit page:
The "new_data" block of ad_form doesn't look quite right; either use the "samplenote::new" wrapper _or_ the db_dml statement, but not both at the same time 😊. (Don't forget to include an example derrived from ,e.g., "forum::new" if you follow the wrapper path.)