Skip to content

feat(bin): add opt-in per-project external contract mode - #3490

Open
jleemcf wants to merge 1 commit into
kunchenguid:mainfrom
jleemcf:fm/fm-project-external-contract-mode-e5
Open

feat(bin): add opt-in per-project external contract mode#3490
jleemcf wants to merge 1 commit into
kunchenguid:mainfrom
jleemcf:fm/fm-project-external-contract-mode-e5

Conversation

@jleemcf

@jleemcf jleemcf commented Sep 2, 2026

Copy link
Copy Markdown

Summary

Add an opt-in per-project external-contract mode while preserving byte-identical brief output for every ordinary project.
A marked project's complete private operating contract is embedded inline in every ship and scout brief.
Brief generation refuses rather than proceeding when that contract is absent, empty, unreadable, or cannot be read completely.

Reviewer note: This branch history was rewritten to remove private fixture identifiers before publication.
The pull request therefore requires a force-push to update its existing branch in place.

Behavior

  • bin/fm-project-mode.sh resolves the independent +external-contract annotation without changing delivery posture.
  • Marked ship and scout briefs contain one complete contract snapshot, never only a path.
  • The authoritative delivery marker cannot be produced, moved, or shadowed by contract bytes, including after scout promotion.
  • The embedded section states that the private contract must not appear in commits, pull request text, evidence files, or any other published surface.
  • Marked ship briefs omit the ordinary project-memory section and direct agent-specific knowledge back through Firstmate.
  • bin/fm-ensure-agents-md.sh refuses in-repository agent-file creation for marked projects with a generic project-facing policy message.
  • Local and remote home seeding pair the marker and complete contract atomically or refuse before publishing either half.
  • Remote rollback restores marker and contract together, and remote convergence removes contracts for projects it delists.
  • Unknown flags in well-formed bracketed registry annotations are refused instead of silently selecting ordinary behavior.

Accepted guarantees

  • A marked ship brief embeds the complete contract exactly once.
  • A marked scout brief embeds the complete contract exactly once.
  • Ordinary ship, scout, Herdr-lab, and secondmate briefs remain byte-identical to committed pre-change baseline fixtures.
  • Missing, empty, unreadable, and incomplete contracts return nonzero, name <firstmate-home>/data/project-contracts/<marked-project>.md, and write no brief.
  • The agent-file helper writes neither AGENTS.md nor CLAUDE.md for a marked project.
  • Marked briefs contain neither # Project memory nor an instruction to invoke the agent-file helper.

Publication verification

The rewritten branch contains one feature commit on current base 77ee3c82f86ea9db4cbcfa39d226361dfa7868e8.
Every commit diff that would be published was scanned, not only the final file tree.
No would-be-published commit carries the private project identifier, private origin identifier, private registry row, client identifier, or an absolute path under the operator's home.
The reconstructed commit tree is byte-identical to the accepted rebased result.

Verification

Passed locally:

bin/fm-test-run.sh tests/fm-brief.test.sh tests/fm-ensure-agents-md.test.sh tests/fm-task-delivery.test.sh
bin/fm-test-run.sh tests/fm-fleet-sync.test.sh tests/fm-secondmate-safety.test.sh
bin/fm-doc-audience-check.sh
bin/fm-lint.sh

The external-contract remote-seeding, fail-closed transfer, rollback, and delisting cases also pass in tests/fm-remote-secondmate-lifecycle-e2e.test.sh.
That full suite later fails at first inheritance transaction never reached its blocked write on both this branch and unchanged base 77ee3c82f86ea9db4cbcfa39d226361dfa7868e8.
The identical base failure is pre-existing and tracked separately; this change does not skip, disable, quarantine, or mark the case as expected to fail.

Risk

Medium because the opt-in contract now travels with marked project records during local and remote home seeding.
The transfer uses the existing private transport, validates complete bytes and destination containment, and rolls back both marker and contract together on failure.
Ordinary projects remain on the committed byte-identical baseline path.

Delivery

This updates pull request 3490 and its existing branch in place.
The upstream maintainer retains merge authority.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T02:37:42.544493Z 4ffd739 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Reviews (3): Last reviewed commit: "feat: add per-project external contract ..." | Re-trigger Greptile

Comment thread bin/fm-brief.sh Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ffd739ad7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread bin/fm-brief.sh
{TASK}

$HERDR_SECTION
$PROJECT_CONTRACT_SECTION$HERDR_SECTION

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve external-project rules when promoting scouts

Captain, when a marked scout is promoted in place, its original scaffold contains the contract snapshot but not the # External project knowledge section, while fm-promote.sh adds only generic ship instructions and the definition of done. The resulting ship worker is never told not to modify AGENTS.md, CLAUDE.md, or agent skills, nor to return durable agent knowledge through firstmate, so this supported lifecycle can commit exactly the files external-contract mode is intended to prevent. Include these rules in the marked scout scaffold so they survive promotion, or add them during promotion.

AGENTS.md reference: AGENTS.md:L522-L524

Useful? React with 👍 / 👎.

Comment thread bin/fm-brief.sh
Comment on lines +308 to +309
if [ ! -f "$EXTERNAL_CONTRACT_PATH" ] || [ ! -r "$EXTERNAL_CONTRACT_PATH" ] || [ ! -s "$EXTERNAL_CONTRACT_PATH" ]; then
refuse_external_contract

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Seed external contracts into secondmate homes

Captain, when a local or remote secondmate is provisioned with a marked project, fm-home-seed.sh and fm-remote-home-seed.sh copy the registry row—including +external-contract—but never copy or validate data/project-contracts/<project>.md. This lookup therefore resolves a nonexistent destination-home path, and the new preflight rejects every ship and scout brief in an otherwise successfully provisioned home. Copy or explicitly provision and validate the contract atomically with the marked registry row.

AGENTS.md reference: AGENTS.md:L262-L264

Useful? React with 👍 / 👎.

@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate: first look on HEAD 7f9c46addbbe080a542666353d97f131c4698c21.

Contract-class: opt-in (verified). Unconfigured / unmarked projects stay on the ordinary path: fm-project-mode.sh --external-contract prints nothing unless the registry row carries an explicit +external-contract token; ordinary ship/scout/Herdr-lab/secondmate briefs are pinned byte-identical to the f42a629 baseline fixtures; fm-ensure-agents-md.sh only refuses when a registered clone/origin matches a marked row. Not a default-on flip.

Attestation: MISSING. PR body has no bound raise SHA. Require no-mistakes failed on this HEAD (33583920001 / 33584256879 — Verify no-mistakes signature and pipeline attestation). Please rebind attestation to this HEAD (or re-raise) so NM can pass.

CI this pass: first-time fork workflows approved for this HEAD — CI 33583919873 (now in_progress); NM 33583920001 and 33584256879 (both FAIL attestation as above). Greptile SUCCESS on the later tip. workflow-zero (no .github/workflows/*).

Mergeable: CONFLICTING vs current main (1c41029972f8, ahead 5 / behind 7). Not auto-merge-ready yet.

Residuals to clear before merge (author):

  1. Attestation bind + green NM.
  2. Rebase/resolve conflicts onto current main (do not leave CONFLICTING).
  3. Codex P1: scout→ship promote via fm-promote.sh does not carry # External project knowledge / no-AGENTS rules — marked scout promotion can still write project agent files. Fix in scout scaffold or promote path.
  4. Codex P2: fm-home-seed.sh / fm-remote-home-seed.sh copy the +external-contract registry row but do not provision data/project-contracts/<project>.md, so a freshly seeded secondmate home refuses every brief for that marked project.

Waiting on author — not a captain hold. Greptile's earlier NUL-truncation finding looks addressed on this HEAD (byte-count + NUL refuse).

@jleemcf
jleemcf force-pushed the fm/fm-project-external-contract-mode-e5 branch from 7f9c46a to b47a5da Compare September 2, 2026 20:02
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.

2 participants