I thought this was a bug in 2.1.3, but in 2.2.0rc1 it's still here...
To the best of my understanding, the "Direct DID" option in the extension configuration is meant to avoid the need to create an Inbound Route with any CID / that DID number and point it to the given extension.
I created an extension, WXYZ which is mapped to a telco DID TUVWXYZ - I defined TUVWXYZ in the "Direct DID" - and of course removed the Inbound route that I create to avoid the bug...
Here is /var/log/asterisk/full for an incoming call to the TUVWXYZ ZAP DID
Dec 1 10:30:14 VERBOSE[3153] logger.c: -- Accepting call from '<hidden-10-digits-number-to-protect-the-innocent>' to 'TUVWXYZ' on channel 0/26, span 1
Dec 1 10:30:14 DEBUG[3153] chan_zap.c: Enabled echo cancellation on channel 26
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Set("Zap/26-1", "DID=TUVWXYZ") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Goto("Zap/26-1", "s|1") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Goto (from-zaptel,s,1)
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing NoOp("Zap/26-1", "Entering from-zaptel with DID == TUVWXYZ") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Ringing("Zap/26-1", "") in new stack
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: Requested indication 3 on channel Zap/26-1
Dec 1 10:30:14 DEBUG[8876] pbx.c: Expression result is '0'
Dec 1 10:30:14 DEBUG[8876] pbx.c: Function result is 'TUVWXYZ'
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Set("Zap/26-1", "DID=TUVWXYZ") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing NoOp("Zap/26-1", "DID is now TUVWXYZ") in new stack
Dec 1 10:30:14 DEBUG[8876] pbx.c: Expression result is '1'
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing GotoIf("Zap/26-1", "1?zapok:notzap") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Goto (from-zaptel,s,8)
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing NoOp("Zap/26-1", "Is a Zaptel Channel") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Set("Zap/26-1", "CHAN=26-1") in new stack
Dec 1 10:30:14 DEBUG[8876] pbx.c: Function result is '26'
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Set("Zap/26-1", "CHAN=26") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Macro("Zap/26-1", "from-zaptel-26|TUVWXYZ|1") in new stack
Dec 1 10:30:14 WARNING[8876] app_macro.c: No such context 'macro-from-zaptel-26' for macro 'from-zaptel-26'
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing NoOp("Zap/26-1", "Returned from Macro from-zaptel-26") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Executing Goto("Zap/26-1", "ext-did|TUVWXYZ|1") in new stack
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Goto (ext-did,TUVWXYZ,1)
Dec 1 10:30:14 WARNING[8876] pbx.c: Channel 'Zap/26-1' sent into invalid extension 'TUVWXYZ' in context 'ext-did', but no invalid handler
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[8876] cdr_addon_mysql.c: cdr_mysql: inserting a CDR record.
Dec 1 10:30:14 DEBUG[8876] cdr_addon_mysql.c: cdr_mysql: SQL command as follows: INSERT INTO cdr (calldate,clid,src,dst,dcontext,channel,dstchannel,las
tapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid) VALUES ('2006-12-01 10:30:14','<hidden-10-digits-number-to-protect-the-innocent>','<hidden-10-digits-number-to-protect-the-innocent>','TUVWXYZ','ext-did', '
Zap/26-1','','Goto','ext-did|TUVWXYZ|1',0,0,'NO ANSWER',3,'','1164961814.8014')
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 DEBUG[3142] channel.c: Avoiding initial deadlock for 'Zap/26-1'
Dec 1 10:30:14 WARNING[3142] channel.c: Avoided initial deadlock for '0x99df570', 10 retries!
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: Set option AUDIO MODE, value: ON(1) on Zap/26-1
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: Hangup: channel: 26 index = 0, normal = 42, callwait = -1, thirdcall = -1
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: Not yet hungup... Calling hangup once with icause, and clearing call
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: disabled echo cancellation on channel 26
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: Set option TDD MODE, value: OFF(0) on Zap/26-1
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: Updated conferencing on 26, with 0 conference users
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: Set option AUDIO MODE, value: OFF(0) on Zap/26-1
Dec 1 10:30:14 DEBUG[8876] chan_zap.c: disabled echo cancellation on channel 26
Dec 1 10:30:14 VERBOSE[8876] logger.c: -- Hungup 'Zap/26-1'
Obviously, creating an Inbound rule to any CID / TUVWXYZ and pointing it to the relevant extension - works...