Skip to content

feat: add deterministic operation catalog foundation - #325

Merged
Joncallim merged 3 commits into
mainfrom
codex/issue-201-operation-catalog
Aug 7, 2026
Merged

feat: add deterministic operation catalog foundation#325
Joncallim merged 3 commits into
mainfrom
codex/issue-201-operation-catalog

Conversation

@Joncallim

@Joncallim Joncallim commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Summary

Part of #201.

This draft adds the first bounded foundation for Forge's deterministic Operation Catalog:

  • a strict, versioned operation request and code-owned catalog;
  • three fixed read-only operations: repository status, diff summary, and current branch;
  • authoritative task, project, work-package, filesystem-grant, and repository-root checks;
  • audited argv-based Git execution with cancellation and deterministic verification;
  • a PostgreSQL operation ledger with ordered append-only phase events, idempotent replay, canonical outcomes, and tamper fingerprints;
  • ADR 0011 and unit, security-regression, migration, privilege, and hosted PostgreSQL behavior tests.

Safety boundaries

  • Model output cannot supply a path, working directory, command, argv, adapter, server, or tool name.
  • Repository reads require a current approved/running task and an always_allow filesystem.project.read grant. allow_once fails closed because this slice does not atomically consume it.
  • Git diff uses --no-ext-diff --no-textconv; a malicious textconv regression proves repository configuration cannot execute a helper.
  • Failed, cancelled, and timed-out commands retain bounded command-audit evidence without copying raw output into the operation ledger.
  • This slice does not add writes, arbitrary shell, GitHub/MCP mutation, project-local registrations, autonomy promotion, or retry automation.

Validation

  • Full unit suite, including a live-PostgreSQL operation-ledger proof: passing in CI.
  • Full ESLint: passed.
  • Orthogonal review: no blockers in this draft-foundation scope; advisory findings addressed (best-effort ledger writes, admission-block test coverage, real database error surfaced instead of a generic driver wrapper, PUBLIC-execute revoked on the new trigger functions).
  • Migration journal parity: 31 SQL migrations / 31 journal entries; latest 0030_operation_runs.

Stack and follow-ons

This PR previously stacked on draft PR #324, which has since merged; this branch is now retargeted directly onto main.

This PR intentionally does not close #201. Follow-ons before full issue closure include:

  • connecting executeTrustedOperation to the normal task/model worker path;
  • fenced stale-run lease and recovery;
  • independent Workforce verification and autonomy integration;
  • MCP-health integration after its dependency chain supports real cancellation;
  • stronger filesystem containment before broader reads or any write operation.

@Joncallim
Joncallim force-pushed the codex/issue-201-operation-catalog branch 3 times, most recently from 8d9a57e to 4b2017d Compare August 7, 2026 02:44
@Joncallim
Joncallim changed the base branch from agent/normalize-execution-outcomes to main August 7, 2026 07:15
Joncallim and others added 3 commits August 7, 2026 07:15
…r functions

New PL/pgSQL functions default to PUBLIC EXECUTE in Postgres unless
explicitly revoked, matching every other custom routine in this codebase
(e.g. migration 0025's REVOKE ALL ... FROM PUBLIC for
forge_epic_172_reject_mutation_v1, and the block of REVOKEs in migration
0027). Migration 0030 skipped this for its three new trigger functions,
so forge_project_root_reconciler picked up implicit EXECUTE via PUBLIC and
failed the closed root-reconciler effective-privilege allowlist proof in
CI ("unexpected": [...forge_guard_operation_event_insert_v1, ...]).
drizzle-orm (^0.45.2) wraps every failed query in a DrizzleQueryError whose
message is a generic "Failed query: insert into ... params: ..." dump; the
actual driver/database error -- e.g. the text a trigger raises via RAISE
EXCEPTION, such as "operation run events must be appended in phase order"
-- is only reachable via `.cause`. appendEvent and finalize now unwrap it,
so callers (and operators reading logs) see the real rejection reason
instead of an opaque wrapper. Caught by
operation-ledger.postgres.test.ts's live-Postgres proof, which asserts on
that exact trigger message.
@Joncallim
Joncallim force-pushed the codex/issue-201-operation-catalog branch from f787587 to d2b12c4 Compare August 7, 2026 07:15
@Joncallim
Joncallim marked this pull request as ready for review August 7, 2026 07:34
@Joncallim
Joncallim merged commit 828a086 into main Aug 7, 2026
4 of 5 checks passed
@Joncallim
Joncallim deleted the codex/issue-201-operation-catalog branch August 7, 2026 07:38
Repository owner deleted a comment from chatgpt-codex-connector Bot Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add deterministic operation catalog and typed execution harness

2 participants