This is just a curt supplement to Faré's answer. (Hopefully I won't be bothered anymore by common-lisp.net antispam machinery.)
Is there some reason why we must put the external-format into the property list instead of just giving it a slot in the component class definition?
It was my ignorance.
Also, what sort of an entity are the external format values? Is it always a keyword symbol? Can we say that it should always be a keyword and that we will massage it to something else, if necessary, for the benefit of the implementation when reading a file?
Maybe yes. Consider that e.g. some implementations accept more options (mostly to control line terminators) — CLISP as instances of ext:encoding, LispWorks as lists like '(:latin-1 :eol-style :lf); but then CLISP explicitly says that line terminators don't matter during input.
In that case we could have an accessor that will do the implementation-specific massaging for us (e.g., we could store :utf-8, but on clisp we would present charset:utf-8 when reading...). That seems somehow tidier to me, rather than changing the value behind the programmer's back as we do here. OTOH, we do quietly change symbols to strings, so maybe I'm just talking through my hat.
I'd appreciate if you explain in a more detail what happens when and how. Is it like in the attached patch, but with logic moved from the setf'er to the accessor?
I wasn't sure I understood the following paragraph, either
If one goes beyond ASCII, saves not in UTF-8 (as expected on MS Windows, but even on Linux LispWorks Personal IDE tried to save a file in Latin-1), manages local projects with ASDF and upgrades ASDF, he will be affected.