docgov saves content hashes through the new leaf module so it no longer
imports docrevision. Existing docrevision exports stay as thin wrappers.
Co-authored-by: Cursor <cursoragent@cursor.com>
Cross-module callers get an opaque ref plus rotating lease tokens so stale writers fail closed, and file I/O is refused inside a unit of work.
Co-authored-by: Cursor <cursoragent@cursor.com>
Authorize first, then return immutable ledger markdown with typed consistency so a missing or drifted projection is no longer a 404/409. GET stays read-only and FAV degraded read stays off.
Co-authored-by: Cursor <cursoragent@cursor.com>
Lock the document row and re-authorize duty before edit, agent commit, approve, or reject share a single transaction. Characterization tests pin ETag races, one legal approve/reject terminal, and same-key digest conflicts.
Co-authored-by: Cursor <cursoragent@cursor.com>
Give each document command one postgres transaction and only let table owners unwrap the scope, so cross-owner writes can roll back together.
Co-authored-by: Cursor <cursoragent@cursor.com>
migration_repair is not a human revision. HashUpdater now loads from DB
and retries still sync. Content reads return a structured drift conflict
instead of the destructive old head.
Co-authored-by: Cursor <cursoragent@cursor.com>
Remove now reconciles document slots and returns ERR_DUTY_SYNC on
failure. CreateOrGetDocument errors abort the task. The frontend
refreshes workflow docs after add, update, restore, and remove.
Co-authored-by: Cursor <cursoragent@cursor.com>
Align document slots to project document_duty even when the wrong ID is
an active member, and fail generate/list instead of returning stale
placeholder duties. Owner author backfill now picks creator, else lowest ID.
Co-authored-by: Cursor <cursoragent@cursor.com>
Stop inventing reviewer_id=2. Use project document_duty as the authority, heal missing or non-member placeholders, and keep write paths rejected for reviewer and outsiders.
Co-authored-by: Cursor <cursoragent@cursor.com>
ListWorkflowDocumentsByProject now projects author/reviewer/approver
id+name so clients cannot invent the current user as author.
Co-authored-by: Cursor <cursoragent@cursor.com>
Do not expose a production path that mutates only the in-memory proposal
index. Cover decision idempotency via ProposeModification+Decide and the
existing package MarkProposalApplied tests instead.
Co-authored-by: Cursor <cursoragent@cursor.com>
Write applied status to Postgres before mutating memory so a failed UPDATE
cannot leave a false in-memory applied state; treat already-applied as
idempotent success and expose PutChangeProposal for compensation seeding.
Co-authored-by: Cursor <cursoragent@cursor.com>
Unauthorized actors no longer grab leases; controlled PATCH projects through
DocGov so author_last_edited and audit survive, with idempotent retry on failure.
Co-authored-by: Cursor <cursoragent@cursor.com>
Stage generation without a real document must not panic or enter the ledger.
Unknown orphan IDs are denied, write paths check author/lease/lifecycle, PATCH
no longer returns a fake 200, and overlay matching survives client/server block id drift.
Co-authored-by: Cursor <cursoragent@cursor.com>
Use task run_id as doc lease holder so release tracks execution, and reclaim squad locks when the holder run is missing or no longer running.
Co-authored-by: Cursor <cursoragent@cursor.com>
Sync doc task status on approve and evaluate whether to emit stage advance readiness; chain docgov hooks.
Co-authored-by: Cursor <cursoragent@cursor.com>
Unify auth middleware and remove X-User-ID trust, add project_members
authorization, sandbox workspaces via resolver, and admin-only reconcile
by run_id. Introduce goose migrations with startup schema gate, fail closed
when DB unavailable outside explicit ALLOW_IN_MEMORY, bundle web/dist in
app Dockerfile, and remove frontend pseudo-login fallback.