feat(content): add doc_notes column for the documenter's own slot

This commit is contained in:
Renn F
2026-06-21 01:58:43 +02:00
parent a6e09f6d75
commit 31c2d5adc6
5 changed files with 21 additions and 3 deletions
@@ -1,9 +1,11 @@
"""Structured content columns + quick_context machine-marker split.
Adds three nullable columns to ``tasks``:
Adds four nullable columns to ``tasks``:
- ``pr_reviewer_notes`` (TEXT) — the PR reviewer's own rendered note slot, so a
review no longer overwrites ``qa_notes`` / ``dev_notes``.
- ``doc_notes`` (TEXT) — the documenter's own rendered note slot (doc content
used to leak into the human ``quick_context`` blob).
- ``notes_structured`` (JSON) — the typed source of truth for every role's
structured note (the TEXT note columns become a derived mirror).
- ``orchestration_markers`` (JSON) — the machine markers that used to be packed
@@ -102,6 +104,7 @@ def _parse_quick_context(blob: str | None) -> tuple[dict, str | None]:
def upgrade() -> None:
op.add_column("tasks", sa.Column("pr_reviewer_notes", sa.Text(), nullable=True))
op.add_column("tasks", sa.Column("doc_notes", sa.Text(), nullable=True))
op.add_column(
"tasks", sa.Column("notes_structured", postgresql.JSON(), nullable=True)
)
@@ -141,4 +144,5 @@ def downgrade() -> None:
# Lossy by design: markers are not re-merged back into quick_context.
op.drop_column("tasks", "orchestration_markers")
op.drop_column("tasks", "notes_structured")
op.drop_column("tasks", "doc_notes")
op.drop_column("tasks", "pr_reviewer_notes")
+2
View File
@@ -236,6 +236,7 @@ class TaskUpdate(BaseModel):
qa_notes: str | None = None
auditor_notes: str | None = None
pr_reviewer_notes: str | None = None
doc_notes: str | None = None
quick_context: str | None = None
# Lifecycle override — privileged/admin only. Applied by the route as an
@@ -335,6 +336,7 @@ class TaskResponse(BaseModel):
qa_notes: str | None
auditor_notes: str | None = None
pr_reviewer_notes: str | None = None
doc_notes: str | None = None
quick_context: str | None
notes_structured: dict | None = None
orchestration_markers: dict | None = None
+1
View File
@@ -345,6 +345,7 @@ class TaskTable(Base):
# quick_context (never human-facing). pr_reviewer_notes is the reviewer's
# own slot so a review no longer overwrites qa_notes / dev_notes.
pr_reviewer_notes: Mapped[str | None] = mapped_column(Text, nullable=True)
doc_notes: Mapped[str | None] = mapped_column(Text, nullable=True)
notes_structured: Mapped[dict[str, Any] | None] = mapped_column(JSON, nullable=True)
orchestration_markers: Mapped[dict[str, Any] | None] = mapped_column(
JSON, nullable=True
+4
View File
@@ -251,6 +251,9 @@ class Task(TimestampMixin):
pr_reviewer_notes: str | None = Field(
default=None, description="PR reviewer's rendered verdict (own slot)"
)
doc_notes: str | None = Field(
default=None, description="Documenter's rendered note (own slot)"
)
notes_structured: dict | None = Field(
default=None,
description="Typed structured note payloads — the source of truth",
@@ -390,6 +393,7 @@ class TaskUpdate(RobocoBase):
auditor_notes: str | None = None
quick_context: str | None = None
pr_reviewer_notes: str | None = None
doc_notes: str | None = None
# Git fields
task_type: TaskType | None = None
@@ -8,21 +8,28 @@ from roboco.models.task import TaskUpdate as DomainTaskUpdate
def test_api_task_update_accepts_auditor_and_pr_reviewer_notes() -> None:
u = ApiTaskUpdate(auditor_notes="audit", pr_reviewer_notes="review")
u = ApiTaskUpdate(
auditor_notes="audit", pr_reviewer_notes="review", doc_notes="doc"
)
assert u.auditor_notes == "audit"
assert u.pr_reviewer_notes == "review"
assert u.doc_notes == "doc"
def test_domain_task_update_accepts_new_notes() -> None:
u = DomainTaskUpdate(auditor_notes="audit", pr_reviewer_notes="review")
u = DomainTaskUpdate(
auditor_notes="audit", pr_reviewer_notes="review", doc_notes="doc"
)
assert u.auditor_notes == "audit"
assert u.pr_reviewer_notes == "review"
assert u.doc_notes == "doc"
def test_task_response_exposes_structured_fields() -> None:
fields = set(TaskResponse.model_fields)
assert {
"pr_reviewer_notes",
"doc_notes",
"notes_structured",
"orchestration_markers",
} <= fields