Shaders that are to be linked together in a program object must first be attached to that program object. glAttachShader attaches the shader object specified by shader to the program object specified by program. This indicates that shader will be included in link operations that will be performed on program.
After the link operation, applications are free to modify attached shader objects, compile attached shader objects, detach shader objects, delete shader objects, and attach additional shader objects. None of these operations affects the information log or the program that is part of the program object.
From this we can infer that the sole purpose of attaching a shader is for linking, and once linking is completed whether or not a shader is attached has no relevance.
So you attach one or more shaders, you link the program, the GLSL compiler takes the attached shaders and copies them off to the final linked program object, following which the shaders need no longer exist.
It may help to understand that OpenGL is quite a high-level abstraction and that many of it's constructs don't (or no longer) reflect how the underlying hardware actually works. This is particularly true of the GLSL interfaces, where it can be argued that they were never a good match for hardware in the first place. No other API has the concept of a linked program object that holds it's own state.