Based on a "git pull" comment you've made I have to assume you're a developer. You make a good point on not altering the DB structure. Anyway, you could just add new tables and that won't interfere with the core at all. You can even display these posts in a separate page (page plugin). However, you'd have to implement the voting system on your own (that's a lot of work).
If you try to filter out questions tagged with a particular tag from questions lists you'll have to modify some queries, which are part of the core. So you will be modifiying the core in this case. You'll also need to create a page plugin in this case that would list the questions you're leaving out in the first queries.
A variation to filter out questions without changing the core would be to filter them out after performing the query in order to avoid changing the core but you'll end up with awkward question counts in each page. In this approach you would be actually using questions posts so the voting feature would be present for them and you can almost reuse the presentation logic from the core in your plugin (you will still have to create a page plugin for displaying this particular questions).
The last scenario I've seen someone mentioned some time ago, which is a variation of the first one and I don't find any benefit at all of it, is adding a new post type and store it in the ^posts table. It shouldn't interefer with the core as the core filters them based on the type and queries which use this kind of WHERE clauses field like 'Q%'. So you could try to add new posts there. But again, although you would keep the foreign keys to the table holiding the votes you still have to apply the voting logic to it. This scenario was actually suggested based on a question that dind't require voting on the new post types.
Conclusion: try to flexibilize the requirements (remove voting and go for the first or fourth approach), modify the core (and go for the second approach) or accept question lists might/will loose items when displaying them (this is the third approach). I can not think of anything else right now but should be enough to get you started :)
Edit: Core hack approach
Look for this line in qa_db_unanswered_qs_selectspec function in qa-include/db/selects.php
$selectspec['source'].=" JOIN (SELECT postid FROM ^posts WHERE ".
qa_db_categoryslugs_sql_args($categoryslugs, $selectspec['arguments']).
"type=$ AND ".$bysql.
" AND closedbyid IS NULL ORDER BY ^posts.created DESC LIMIT #,#) y ON ^posts.postid=y.postid";
Change it with this line:
$selectspec['source'].=" JOIN (SELECT postid FROM ^posts WHERE ".
qa_db_categoryslugs_sql_args($categoryslugs, $selectspec['arguments']).
"type=$ AND ".$bysql.
" AND closedbyid IS NULL AND NOT FIND_IN_SET('publication', tags) ORDER BY ^posts.created DESC LIMIT #,#) y ON ^posts.postid=y.postid";
Alternatively, you could join twice to reach ^words but I guess the double join will be worse than the string search. Alternatively, you could manually from the DB fetch the id for the word 'publication' and just join with ^posttags using that ID. However, when the ID changes, maybe after reindexing you'll have to manually get the ID again and force it in the query.