Organizing a comments table: How to justify the choice?
This is not really an answer, but more of a set of reflections. However it is to long for a comment so I'll add it as an answer anyhow. These are the base tables if I get it right:

CREATE TABLE USER
( USER_ID ... NOT NULL PRIMARY KEY
, ... );

CREATE TABLE MONEY
( MONEY_ID ... NOT NULL PRIMARY KEY
, ... );

CREATE TABLE PROGRESS
( PROGRESS_ID ... NOT NULL PRIMARY KEY
, ... );


Since I don't know your business I just invented some identifier as a primary key. It may very well be a composite key, but for simplicity I do it like this.

Alternative 1:

CREATE TABLE comment 
( user_id ... not null references USER (user_id)
, text ...
, created_at ...
, subject_type ... -- 'money' or 'progress'
, subject_id ... -- identifier from 'money' or 'progress'
);


In all essential this is a union type for comments on either MONEY or PROGRESS. It is a construction that does not really fit well in a relational world. One major drawback is that it will not be possible to implement referential integrity (foreign key). I'm not sure what the primary key would be here.

Alternative 2:

I'm not sure I understand what you are saying here. Is MONEY dependent of the COMMENT? I.e.

CREATE TABLE comment (
    id…, -- not unique
    created_at ... not null
    user_id… not null references USER (user_id)
    text ... not null
    CONSTRAINT comment_pk PRIMARY KEY (id, created_at)
);

ALTER TABLE MONEY ADD CONSTRAINT ...
    FOREIGN KEY (MONEY_ID, created_at) -- add created_at in MONEY
    REFERENCES COMMENT (id, created_at);


and similar for PROGRESS. If this is what you mean then the COMMENT will have to exist before MONEY or PROGRESS and this seems counter intuitive to me.

Alternative 3

I would probably change the name to:

CREATE TABLE MONEY_COMMENT
( MONEY_ID ... REFERENCES MONEY (MONEY_ID)
, USER_ID ... REFERENCES USER (USER_ID)
, CREATED_AT ...
, ...
,    PRIMARY KEY (MONEY_ID, USER_ID, CREATED_AT) );


and a similar table PROGRESS_COMMENT. I share your thoughts that this is the most elegant solution. If you are interested in all COMMENTS by a USER you can create a view like:

CREATE VIEW COMMENTS AS 
    SELECT 'money' as COMMENT_TYPE
         , MONEY_ID AS COMMENT_ID
         , USER_ID
         , CREATED_AT 
         , ...
    FROM MONEY_COMMENT
    UNION ALL
    SELECT 'progress' as COMMENT_TYPE
         , PROGRESS_ID AS COMMENT_ID
         , USER_ID
         , CREATED_AT 
         , ...
    FROM PROGRESS_COMMENT