Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/plans/2026-06-10-capture-seq-determinism.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**Date:** 2026-06-10
**Branch:** work/clerk-persistence-phase-1
**Bug:** All four CivicClerk persistence repositories (`civicclerk/motion_vote.py`,
**Bug:** All four CivicMeetings persistence repositories (`civicclerk/motion_vote.py`,
`civicclerk/minutes.py`, `civicclerk/public_archive.py`) order list reads by
`(created_at, id)`. `id` is a random uuid4, so rows inserted within the same
timestamp tick tiebreak randomly and insertion order is not preserved.
Expand Down
6 changes: 3 additions & 3 deletions .claude/plans/2026-06-10-clerk-persistence-phase-1.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CivicClerk Persistence Phase 1 Implementation Plan
# CivicMeetings Persistence Phase 1 Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

Expand Down Expand Up @@ -918,7 +918,7 @@ class MinutesDraftRepository:
if not is_known_prompt_version(prompt_version):
expected = expected_prompt_version_hint()
return MinutesValidationError(
message="Minutes drafts must use a prompt version from the CivicClerk YAML prompt library.",
message="Minutes drafts must use a prompt version from the CivicMeetings YAML prompt library.",
fix=f"Use prompt_version '{expected}' or another version returned by the prompt library.",
)

Expand Down Expand Up @@ -2070,7 +2070,7 @@ Persistence Phase 1 update: motions, votes, action items, minutes drafts,
public archive records, and resident comments now persist to the configured
database when `CIVICCLERK_MOTION_VOTE_DB_URL`, `CIVICCLERK_MINUTES_DB_URL`,
and `CIVICCLERK_PUBLIC_ARCHIVE_DB_URL` are set, so the legal record of a
meeting survives an API restart. Without those variables CivicClerk falls
meeting survives an API restart. Without those variables CivicMeetings falls
back to in-memory stores and the legal record does not survive a restart —
do not run a real public meeting without database-backed persistence
enabled. Transcript records, ordinance/resolution handoffs, notice records,
Expand Down
34 changes: 34 additions & 0 deletions .fablize/goals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"brief": "Fix 3 flaky list-ordering tests in civicmeetings (timestamp tie-break nondeterminism)",
"created": "2026-07-10T03:48:23.058893+00:00",
"goals": [
{
"id": "G001",
"title": "G1-baseline",
"objective": "10x repeated runs of the 3 flaky tests with per-test failure counts recorded",
"status": "pending",
"evidence": null
},
{
"id": "G002",
"title": "G2-root-cause",
"objective": "exact ORDER BY sites and tie mechanism identified with file:line evidence",
"status": "pending",
"evidence": null
},
{
"id": "G003",
"title": "G3-fix",
"objective": "deterministic capture_seq secondary sort in notice_checklist, packet_assembly, vendor_sync plus migration 0017",
"status": "pending",
"evidence": null
},
{
"id": "G004",
"title": "G4-proof",
"objective": "10x post-fix runs of the 3 tests with 0 failures plus full affected-file test pass",
"status": "pending",
"evidence": null
}
]
}
1 change: 1 addition & 0 deletions .fablize/ledger.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"ts": "2026-07-10T03:48:23.059893+00:00", "event": "plan_created", "brief": "Fix 3 flaky list-ordering tests in civicmeetings (timestamp tie-break nondeterminism)", "count": 4}
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Bug report
about: Report a CivicClerk bug or documentation issue
about: Report a CivicMeetings bug or documentation issue
title: "[Bug]: "
labels: bug
assignees: ""
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Feature request
about: Suggest a CivicClerk feature
about: Suggest a CivicMeetings feature
title: "[Feature]: "
labels: enhancement
assignees: ""
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cleanroom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
path: civicclerk-cleanroom-${{ github.run_id }}
- name: Verify Docker is available
run: docker version
- name: Run CivicClerk cleanroom harness
- name: Run CivicMeetings cleanroom harness
run: bash scripts/run-civicclerk-cleanroom.sh "$CC1_SHA" "docs/evidence/cc1-ci-${CC1_SHA}"
- name: Upload cleanroom evidence
uses: actions/upload-artifact@v7
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
expected = "${VERSION}"
print(f"civicclerk.__version__={civicclerk.__version__}")
if civicclerk.__version__ != expected:
raise SystemExit(f"Expected CivicClerk {expected}, got {civicclerk.__version__}")
raise SystemExit(f"Expected CivicMeetings {expected}, got {civicclerk.__version__}")
print(
"civiccore dependency import ok: "
f"{CitedSentence.__name__}, {SourceMaterial.__name__}, {validate_cited_sentences.__name__}"
Expand Down Expand Up @@ -242,7 +242,7 @@ jobs:
export WHEEL_URL="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}/civicclerk-${VERSION}-py3-none-any.whl"
export CLEANROOM_TIMESTAMP="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
cat > release-notes.md <<NOTES
CivicClerk ${TAG} runtime foundation release. Built by the release workflow after verify-release.sh passed.
CivicMeetings ${TAG} runtime foundation release. Built by the release workflow after verify-release.sh passed.

Cleanroom rehearsal: PASSED in workflow run ${WORKFLOW_RUN_ID}.
Verified clean install of ${WHEEL_URL} from cold caches at ${CLEANROOM_TIMESTAMP}.
Expand Down Expand Up @@ -281,7 +281,7 @@ jobs:
fi
gh release create "$GITHUB_REF_NAME" \
--draft \
--title "CivicClerk $GITHUB_REF_NAME" \
--title "CivicMeetings $GITHUB_REF_NAME" \
--notes-file release-notes.md \
--verify-tag
mapfile -t release_assets < <(find release-assets -type f -print | sort)
Expand Down Expand Up @@ -348,7 +348,7 @@ jobs:
VERSION="${GITHUB_REF_NAME#v}"
WHEEL="$(find .cleanroom-assets -name 'civicclerk-*-py3-none-any.whl' -type f | head -1)"
if [ -z "$WHEEL" ]; then
echo "::error::No CivicClerk wheel downloaded from draft release."
echo "::error::No CivicMeetings wheel downloaded from draft release."
exit 1
fi
echo "Cleanroom wheel asset: ${WHEEL}"
Expand All @@ -363,7 +363,7 @@ jobs:
expected = "${VERSION}"
print(f"civicclerk.__version__={civicclerk.__version__}")
if civicclerk.__version__ != expected:
raise SystemExit(f"Expected CivicClerk {expected}, got {civicclerk.__version__}")
raise SystemExit(f"Expected CivicMeetings {expected}, got {civicclerk.__version__}")
print(
"civiccore dependency import ok: "
f"{CitedSentence.__name__}, {SourceMaterial.__name__}, {validate_cited_sentences.__name__}"
Expand Down
6 changes: 3 additions & 3 deletions .pipelines/civicclerk-release-plan.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# CivicClerk Productization Release Plan
# CivicMeetings Productization Release Plan

## rung 4: CivicClerk productization sprint
## rung 4: CivicMeetings productization sprint

CivicClerk can be prepared as a productized starter-set module that works cleanly with CivicCore and the CivicSuite installer. This rung covers CivicClerk, CivicCore, and the civicsuite installer starter set. Scope includes: Verify current repo state and run gates directly. Close gaps needed for CivicClerk to work cleanly with CivicCore. Close gaps needed for CivicClerk to fit the installer starter set. Exit criteria: Current gate results are recorded. At least one scoped productization gap is closed with tests. No macOS lifecycle certification is claimed.
CivicMeetings can be prepared as a productized starter-set module that works cleanly with CivicCore and the CivicSuite installer. This rung covers CivicMeetings, CivicCore, and the civicsuite installer starter set. Scope includes: Verify current repo state and run gates directly. Close gaps needed for CivicMeetings to work cleanly with CivicCore. Close gaps needed for CivicMeetings to fit the installer starter set. Exit criteria: Current gate results are recorded. At least one scoped productization gap is closed with tests. No macOS lifecycle certification is claimed.
10 changes: 5 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CivicClerk Agent Instructions
# CivicMeetings Agent Instructions

## Governing Workflow

Expand All @@ -11,7 +11,7 @@ before push or merge.

## Project Purpose

CivicClerk is the CivicSuite module for municipal meeting operations: agenda
CivicMeetings is the CivicSuite module for municipal meeting operations: agenda
intake, packet assembly, statutory notice proof, meeting outcomes, minutes,
public posting, public archives, and CivicCore-backed integration contracts.

Expand All @@ -26,10 +26,10 @@ public posting, public archives, and CivicCore-backed integration contracts.

## Operating Priorities

- Productize CivicClerk as part of the CivicSuite starter set with CivicCore
- Productize CivicMeetings as part of the CivicSuite starter set with CivicCore
and CivicRecords AI.
- Keep CivicCore as the shared base tech. CivicClerk may depend on CivicCore;
CivicCore must not depend on CivicClerk.
- Keep CivicCore as the shared base tech. CivicMeetings may depend on CivicCore;
CivicCore must not depend on CivicMeetings.
- Preserve honest public status language. Do not promote provisional or
mock-only validation as production deployment proof.
- Favor small, verifiable slices that improve installability, CivicCore
Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
# Changelog

All notable changes to CivicClerk are documented here.
All notable changes to CivicMeetings (formerly CivicClerk) are documented here.

## [Unreleased]

### Fixed
- Fixed installed local-AI minutes generation for the Windows-Local bundle.

### Changed
- Renamed the module's public name from CivicClerk to **CivicMeetings** to avoid
confusion with CivicPlus's registered CivicClerk(R) product. Brand-layer rename:
repository, display names, docs, and installer title. Machine identifiers (the
`civicclerk` Python package, database schema, `CIVICCLERK_*` environment
variables, and the `/health` service id) are unchanged in this pass, so
existing installs and pinned consumers are unaffected. Historical records
(ADRs, audit and browser-QA evidence, prior release notes) intentionally keep
the name they shipped under.
- Advanced the CivicCore dependency freeze from `v1.2.0` to the published
`v1.2.1` release wheel. v1.2.1 publishes the `civiccore_0003_local_task_queue`
Alembic migration line that the local-AI minutes path depends on; the v1.2.0
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing to CivicClerk
# Contributing to CivicMeetings

CivicClerk is a planned CivicSuite module. The first contribution
CivicMeetings is a planned CivicSuite module. The first contribution
priority is disciplined MVP delivery: docs, tests, UX evidence, then
code.

Expand Down
4 changes: 2 additions & 2 deletions MILESTONE_0_DONE.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Milestone 0 Done

Milestone 0 reconciled the CivicClerk scaffold against the upstream CivicSuite unified spec, suite ADRs, and the attached AGENTS.md operating contract. No runtime application code was introduced.
Milestone 0 reconciled the CivicMeetings scaffold against the upstream CivicSuite unified spec, suite ADRs, and the attached AGENTS.md operating contract. No runtime application code was introduced.

## Criteria Covered

- Read upstream unified spec sections 4, 5, 9, 15, 16, 17, and 21.
- Read suite ADR-0001, ADR-0002, and ADR-0003 from `CivicSuite/civicsuite`.
- Recorded scaffold-vs-spec disagreements with verbatim current text in `docs/RECONCILIATION.md`.
- Queued v0.1.0-scope open questions as proposed CivicClerk ADRs.
- Queued v0.1.0-scope open questions as proposed CivicMeetings ADRs.
- Added `docs/MILESTONES.md` with milestones 0 through 12, acceptance criteria, and test-count ballparks.
- Replaced the docs verifier with a required-artifact and stale-string gate.
- Added a placeholder-import CI gate for CivicCore v0.2.0 placeholder packages.
Expand Down
4 changes: 2 additions & 2 deletions MILESTONE_10_DONE.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ Status: complete on branch `milestone-10-connectors-imports`

```json
{
"name": "CivicClerk",
"name": "CivicMeetings",
"status": "connector import foundation",
"message": "CivicClerk agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, action-item, and citation-gated minutes draft capture plus permission-aware public calendar and archive endpoints; prompt YAML and offline evaluation gates protect policy-bearing prompt changes; local-first Granicus, Legistar, PrimeGov, and NovusAGENDA imports now normalize source provenance; full UI workflows are not implemented yet.",
"message": "CivicMeetings agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, action-item, and citation-gated minutes draft capture plus permission-aware public calendar and archive endpoints; prompt YAML and offline evaluation gates protect policy-bearing prompt changes; local-first Granicus, Legistar, PrimeGov, and NovusAGENDA imports now normalize source provenance; full UI workflows are not implemented yet.",
"next_step": "Milestone 11: accessibility and browser QA gates"
}
```
Expand Down
4 changes: 2 additions & 2 deletions MILESTONE_11_DONE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ Status: complete on branch `milestone-11-accessibility-browser-qa`

```json
{
"name": "CivicClerk",
"name": "CivicMeetings",
"status": "browser QA gate foundation",
"message": "CivicClerk agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, action-item, and citation-gated minutes draft capture plus permission-aware public calendar and archive endpoints; prompt YAML and offline evaluation gates protect policy-bearing prompt changes; local-first Granicus, Legistar, PrimeGov, and NovusAGENDA imports now normalize source provenance; accessibility and browser QA gates now verify loading, success, empty, error, partial, keyboard, focus, contrast, and console evidence; full UI workflows are not implemented yet.",
"message": "CivicMeetings agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, action-item, and citation-gated minutes draft capture plus permission-aware public calendar and archive endpoints; prompt YAML and offline evaluation gates protect policy-bearing prompt changes; local-first Granicus, Legistar, PrimeGov, and NovusAGENDA imports now normalize source provenance; accessibility and browser QA gates now verify loading, success, empty, error, partial, keyboard, focus, contrast, and console evidence; full UI workflows are not implemented yet.",
"next_step": "Milestone 12: v0.1.0 release"
}
```
Expand Down
4 changes: 2 additions & 2 deletions MILESTONE_12_DONE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Scope

Milestone 12 closes the CivicClerk v0.1.0 runtime-foundation sprint. It synchronizes the release version surfaces, adds the release gate and GitHub release workflow, verifies the package build, and preserves browser QA evidence for the user-facing landing page.
Milestone 12 closes the CivicMeetings v0.1.0 runtime-foundation sprint. It synchronizes the release version surfaces, adds the release gate and GitHub release workflow, verifies the package build, and preserves browser QA evidence for the user-facing landing page.

## Key Commits

Expand Down Expand Up @@ -87,5 +87,5 @@ VERIFY-RELEASE: PASSED
## Boundaries Honored

- No post-v0.1.0 feature work started.
- No CivicSuite compatibility matrix edit is included in this branch; that is performed after the CivicClerk v0.1.0 release is published.
- No CivicSuite compatibility matrix edit is included in this branch; that is performed after the CivicMeetings v0.1.0 release is published.
- No CivicCore changes are included.
4 changes: 2 additions & 2 deletions MILESTONE_1_DONE.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Milestone 1 Done

Milestone 1 created the CivicClerk runtime foundation. It does not implement meeting, agenda, packet, notice, vote, minutes, archive, schema, migration, or frontend workflows.
Milestone 1 created the CivicMeetings runtime foundation. It does not implement meeting, agenda, packet, notice, vote, minutes, archive, schema, migration, or frontend workflows.

## Criteria Covered

- FastAPI runtime package exists at `civicclerk.main:app`.
- Root endpoint explains that the runtime foundation is online and meeting workflows are not implemented yet.
- `/health` endpoint returns service, status, CivicClerk version, and CivicCore version for IT staff.
- `/health` endpoint returns service, status, CivicMeetings version, and CivicCore version for IT staff.
- `pyproject.toml` declares `civicclerk` version `0.1.0.dev0`.
- Runtime dependency is exactly `civiccore==0.2.0`.
- CI installs the package, runs `python -m pytest`, runs `scripts/verify-docs.sh`, and runs `scripts/check-civiccore-placeholder-imports.py`.
Expand Down
10 changes: 5 additions & 5 deletions MILESTONE_2_DONE.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Milestone 2 Done

Milestone 2 added the CivicClerk canonical schema and Alembic migration scaffold. It does not implement agenda lifecycle enforcement, meeting lifecycle enforcement, public pages, search, permissions, or workflow behavior.
Milestone 2 added the CivicMeetings canonical schema and Alembic migration scaffold. It does not implement agenda lifecycle enforcement, meeting lifecycle enforcement, public pages, search, permissions, or workflow behavior.

## Criteria Covered

- `civicclerk.models` defines metadata for all fourteen canonical CivicClerk tables.
- `civicclerk.models` defines metadata for all fourteen canonical CivicMeetings tables.
- All module tables use the `civicclerk` schema.
- Models import and use CivicCore's shared `Base` from `civiccore.db`.
- No competing SQLAlchemy `DeclarativeBase` or `declarative_base()` is declared.
- No foreign keys target CivicCore placeholder packages or unreleased CivicCore shared tables.
- CivicClerk Alembic scaffold exists under `civicclerk/migrations`.
- Alembic env runs the CivicCore migration baseline before CivicClerk migrations.
- CivicMeetings Alembic scaffold exists under `civicclerk/migrations`.
- Alembic env runs the CivicCore migration baseline before CivicMeetings migrations.
- Alembic env boots from one database URL source and runs CivicCore first
in an isolated process against the same URL.
- CivicClerk uses a separate `alembic_version_civicclerk` version table.
- CivicMeetings uses a separate `alembic_version_civicclerk` version table.
- First migration creates the `civicclerk` schema and the fourteen canonical tables with idempotent create-table guards.
- Current-facing docs and CHANGELOG describe the canonical schema and Alembic scaffold without claiming lifecycle/workflow behavior.

Expand Down
4 changes: 2 additions & 2 deletions MILESTONE_6_DONE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ Status: complete on branch `milestone-6-motion-vote-action-capture`

```json
{
"name": "CivicClerk",
"name": "CivicMeetings",
"status": "motion vote action foundation",
"message": "CivicClerk agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, and action-item capture; minutes, archive, and UI workflows are not implemented yet.",
"message": "CivicMeetings agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, and action-item capture; minutes, archive, and UI workflows are not implemented yet.",
"next_step": "Milestone 7: minutes drafting with sentence citations"
}
```
Expand Down
4 changes: 2 additions & 2 deletions MILESTONE_7_DONE.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ Status: complete on branch `milestone-7-minutes-drafting-citations`

```json
{
"name": "CivicClerk",
"name": "CivicMeetings",
"status": "minutes citation foundation",
"message": "CivicClerk agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, action-item, and citation-gated minutes draft capture; archive and UI workflows are not implemented yet.",
"message": "CivicMeetings agenda item, meeting lifecycle, packet snapshot, and notice compliance enforcement are online with immutable motion, vote, action-item, and citation-gated minutes draft capture; archive and UI workflows are not implemented yet.",
"next_step": "Milestone 8: public meeting calendar, detail, and archive"
}
```
Expand Down
Loading