Craig,
Your situation reminds me of the guy whose engine was really clanking, but when his buddy threw a couple of handsful of sawdust in the crankcase, it got rid of the noise. We all know it didn't solve the problem; it just sounded better.
That's what is happening with your query: just because you are getting better results doesn't mean you are getting the "correct" results. First of all, the date situation is a definite failure point. As Issahar mentioned, you really DO need the to_date function; without it, you receive totally coincidental results. Without to_date, your WHERE clause is just doing a straight binary/bit comparison between Oracle's internal date format and the literal characters '09-jul-2003'...which is not even a close comparison. I'll illustrate with the following simple data DUMPs:
select dump('09-jul-2003') from dual;
Typ=96 Len=11: 48,57,45,106,117,108,45,50,48,48,51
select dump(to_date('09-jul-2003')) from dual;
Typ=13 Len=8: 7,211,7,9,0,0,0,0
The first format (without to_date function) produces an 11-byte, character (Type 96) result. The second format (Oracle's standard 8-byte date format, Type 13) is nothing close to the first results. The fact that you are getting output from your SELECT is strictly because the binary representation of (Oracle) dates in your table are coincidentally "less than" the ASCII representation of '09-jul-2003'.
Here is another (less theoretical) example:
Select * from dual where sysdate = '25-Jul-2003';
no rows selected
Select * from dual where sysdate = to_date('25-Jul-2003');
no rows selected
(Surprise, surprise: even this doesn't display records...That is because Oracle dates ALWAYS contain not only the date, but also the time. If we supply no time factor for '25-Jul-2003', then the default time is midnight on the morning of the date ("20030725000000"

. Sysdate contained "20030725101757": 25-Jul-2003 @ 10:17:57 a.m. So, to ignore the TIME factor of SYSDATE we must truncate the time:
Select * from dual where trunc(sysdate) = to_date('25-Jul-2003');
DUMMY
------
X
1 row selected.
So, you MUST use the TO_DATE function (and most likely a TRUNC function) when attempting a comparison between a literal and a DATE expression.
Secondly, the order of evaluation without parentheses in Oracle's SQL (and most other programming languages) is:
1) arithmetic expressions (-,+ before *,/)
2) comparison operators (=, >, <, >=, <=, <>)
3) NOT
4) AND
5) OR
Therefore, without parentheses, your WHERE clause SELECTs data for rows that:
1) PreparedBy = 'Bill Harris' [Specifically, all Bill Harris-prepared rows no matter what date]
or
2) OnBehalfOf = 'Bill Harris' AND CreationDate <= '09-jul-2003' [Specifically, OnBehalfOf-Bill Harris rows whose dates compare less than the spurious '09-jul-2003' character string.]
I recommend always using parentheses to 'force' Oracle to evaluate in the order you want rather than leave order of evaluation up to Oracle's defaults.
Cheers,
Dave Hunt