Skip to content

feat(workflow): publish and resume workflow runs across machines (#1084) - #1280

Merged
jeff-r2026 merged 16 commits into
Tencent:mainfrom
SaulMoro:feat/1084-publish-resume
Oct 24, 2026
Merged

jeff-r2026 merged 16 commits into
Tencent:mainfrom
SaulMoro:feat/1084-publish-resume

Conversation

@SaulMoro

@SaulMoro SaulMoro commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Lets a member hand a running workflow to another machine or teammate, for example when their tool runs out of tokens, or pick up a failed CI run. Part of #818.

Area Rule after this PR
Publish teamai workflow publish <run> [--sessions] writes the run to workflows/runs/<id>/state.json on teamai-reports. The first publish makes this install the owner: a random id in <dataHome>/workflows/owner.json, plus the member's username from the team config for messages, the name run records and labels use. Publishing an unchanged run writes nothing. Another install's run answers not_owner before anything is pushed, drained or archived.
Snapshot snapshot: 1, parsed strictly. Every run and step field is classified publish, drop or rewrite in a table the compiler checks, so a new field does not build until someone decides whether it may leave the machine. It carries what steps did and what expressions read, never driver identities, paths, workflow definitions or failure text. Commit ids are full ids, and branch names stay under teamai/<run>/. A value that looks like a secret, or equals a secret the team declares in env/secrets.yaml, refuses the publish with secret_detected, naming the step, field and label, never the value. A declared secret of 8 or more characters matches anywhere, one of 4 to 7 only as a whole word, and a shorter one is not checked: publish warns and names it. Numbers and booleans are checked as text. An absolute path of this machine (/Users/…, C:\…, \\server\…, ~/…, file://…) in an input, output or note refuses it with local_path_detected, naming the field. URLs, repo-relative paths and route-like text such as /api/v1/users publish.
Concurrency Each write carries a fresh write id on its own line, and the write lands only over the state it read (compare-and-swap inside the reports lock). A write whose push failed stays pending, and the next publish or claim adopts it. A run that changed under a publish answers state_moved.
Resume and claim teamai workflow resume <run> takes a run this machine does not have from teamai-reports. --claim takes it from another owner. Other drivers send claim: true in the next payload. A claim releases every lease and moves an in-flight lease that opened its own copy to the next pass. It rebuilds the workflow definitions at the run's team revision, and refuses with definition_mismatch when they differ. The resume command claims inside the driver lock, so a running driver answers driver_running with nothing claimed.
Workspaces Publish checks each copy's commit on the business origin with ls-remote and pins the base as teamai/<run>/base. It never pushes workspace branches. A driver pushes every commit it reports, failed steps included, and fetches a lease commit it lacks. After a claim, the local driver reconciles its copies once: a clean copy that is behind fast-forwards, and a dirty, ahead, diverged or off-branch copy fails branch_diverged with nothing reset. Origin behind a recorded commit answers commit_missing with the push to run. A claim checks the branches, and the driver reconciles the copies, only while the run is running: a succeeded, failed or cancelled run leases nothing until a retry reopens it, so another member can claim it after a merge deleted its branches, and the first resume after the retry fetches them.
Run end A published run that ends publishes how it ended, under the same checks as publish but without sessions, and a later next or run control retries it after a crash. Once origin holds the end, nothing is checked or pushed again, so deleting the run's branches after a merge changes nothing. A claim of a finished run runs nothing again, also when its branches are gone. A member whose run was claimed meanwhile is told so, and neither the snapshot nor the end record changes.
Sessions --sessions puts the sessions the unsettled steps resume into the team session archive, scrubbed. The driver restores a session from the archive when this machine has no copy. On a git team it reads a temporary clone fetched from origin, and leaves the member's team clone as it is. A step that resumes a session in a copy reports resumed, and the run records that the copy continues it, so the next step gets every turn on any machine. The lease also lists earlier sessions to fall back to, and a report's resumed must name one the lease offered. When this machine cannot read the newest session of a chain, --sessions archives the newest one it can and lists the ones it skipped.
Session commands session push, session migrate --push and session pull write teamai-reports under its lock, and answer busy with exit 1. They first take the archive publication lock from #1334, so a second session command on the same machine waits for the first instead of failing busy. Session commands work on a user-scope install. A session from a workflow step's worktree is filed under the checkout it came from. A retried session save --push pushes the summary a failed push left.
Driver signals With max_parallel: 1, a SIGTERM or SIGHUP sent to the driver alone stops the running command and its children, and the run can be resumed.
Other fixes found on the way Redaction keeps *_PATH values and plain words. Run record stats count per member. Reports commits use a resolvable identity. A failed agent-config reset or merge fails the step and names the files. Nested Copilot paths copy into a fresh worktree.

Decisions

Decision Why
The snapshot is state.json on teamai-reports, not state.yaml as the issue sketched One strict JSON parse, and one field per line, so two concurrent writes conflict on the write line when git rebases one onto the other.
resume is extended with --claim; publish is the only new command Fewer commands. Resuming a run you do not have locally is the same intent.
Sessions are opt-in with publish --sessions Session content can be large and private. The snapshot itself only carries { tool, id } references.
Ownership belongs to an install, not a driver or machine id Two installs on one machine stay distinct, and a driver can move without changing the owner.
Every base is pinned as teamai/<run>/base The driver's one contract fetch covers teamai/<run>/*, so a base that only sits on a moved main or in a shallow CI clone would otherwise be missing on the claiming machine.
Publishing a run in progress stays explicit A reports write per settled step costs every run; the end of a published run is published automatically instead.
Publishing ignores the usage-report setting A published run is shared state that resume needs, not usage telemetry. A run stays off teamai-reports as long as nobody publishes it.
Session commands throw a missing archive to the CLI error boundary Since #1271 that boundary prints any thrown command error as one line with exit 1, so resolveRepoRoot no longer prints and returns undefined itself. session migrate --json still answers archive_failed.

Evidence

Head e70a3339: main merged in again at 6467c3d7 (with #1265). The one conflict was in src/workflow-commands.ts. #1265 passes teamConfig.toolPaths to the local driver instead of scopedToolPaths(...), and this branch's workflow start and workflow resume (under the driver lock) now do the same. tsc --noEmit, lint and build pass. vitest run: 515 files, 14999 tests pass (21 skipped). The six e2e files listed below pass again, 12 tests.

At 3c335f2f: main merged in again at 4b9e0000. The two conflicts were in tests only: workflow-engine.test.ts and workflow-workspace.test.ts keep this branch's resumableSessions import and saveRun helper next to main's _setDriverPollMs(20). tsc --noEmit, lint and build pass. vitest run: 505 files, 12556 tests pass (21 skipped). The six e2e files listed below pass again, 12 tests. The real CLI run below was not repeated at this head.

At ac82dde5: main merged in at 12b80e7f (with #1334). The teamai-reports archive step of session push, session migrate --push and session pull now runs inside #1334's publication lock, and its saves get #1334's rollback. A new test holds that lock in a single-repo team and checks that session push waits for it. It fails on the branch before the merge, where the push finished while the lock was held. tsc --noEmit, lint and build pass. vitest run: 505 files, 12533 tests pass (21 skipped). e2e session-archive-lock, session-migrate-opencode, session-publication, workflow-publish-resume, workflow-records-reports-branch-1083 and reports-writer-sync-561: 6 files, 12 tests pass. Real CLI at ac82dde5 (dist/index.js, teamai init . against a bare business origin, its own HOME, a Claude Code session file, no model runs), 13 checks passed:

# a pre-receive hook holds the first push's teamai-reports update open; a second push starts meanwhile
$ teamai session push --source claude-code --cwd app --scrub -y   # first
  ✓ Pushed 1 session(s) from claude-code                           exit=0
$ teamai session push --source claude-code --cwd app --scrub -y   # second, waits for the first
  ✓ Pushed 1 session(s) from claude-code                           exit=0
teamai-reports holds the session once; main holds no sessions/
$ teamai session migrate <id> -s claude-code -t codebuddy --cwd app --push --scrub -y
  ✓ Pushed 1 session(s) to team repo                               exit=0
$ teamai session pull --cwd app
  ✓ Pulled and indexed 2 session(s)                                 exit=0
# the same two pushes at 060f4483
Error: Another teamai command is writing teamai-reports, so nothing was archived. Run this command again once it has finished.   exit=1

Before that, at 060f4483: short declared secrets and numeric values (a743d72a, 16481355), and main merged in at 6c57c3b7 (with #1302: session migrate --push archives its copy on teamai-reports). vitest run: 499 files, 12478 tests pass (21 skipped). Real CLI: a declared ACCESS_CODE=493827 in inputs.target refuses the publish with secret_detected and does not print the value. DOOR_PIN (42) is named in a warning as too short to protect. build-4938271 publishes. A numeric output 493827 refuses with field outputs.code. The previous head published both. migrate --push in a single-repo team archives on teamai-reports and leaves main without sessions/.

Before that, head 412ea45a, four commits on 0ee0c67c: absolute paths and the team's declared secrets refuse a publish, the owner is named by the team username, and the guide says publishing is not usage reporting. tsc --noEmit and lint pass at each commit. vitest run: 496 files, 12430 tests pass (21 skipped). e2e workflow-publish-resume: 5 of 5. Real CLI at 412ea45a (dist/index.js, two members with their own HOME, bare team and business origins, no model runs):

$ teamai workflow publish <run>        # input file: <tmp>/alice/private/customer-data.csv
{"error":{"code":"local_path_detected","field":"inputs.file", …}}   exit=1, nothing on teamai-reports
$ teamai workflow publish <run>        # an input holds the value of WAREHOUSE_DSN from env/secrets.yaml
{"error":{"code":"secret_detected","field":"inputs.target","label":"WAREHOUSE_DSN", …}}     exit=1, the value is not printed
$ teamai workflow publish <run>        # input file: data/input.csv
owner.user on teamai-reports: alice    # alice's config username; her OS login differs
$ teamai workflow resume <run>         # as bob
owner.user on teamai-reports: bob

Before that, at 0ee0c67c with main merged in (with #1274, #1282, #1285 and #1291). #1291 fixed the same retry on main with a weaker contract; this branch's is kept: a write that returns null pushes nothing, an empty list retries the unpushed commit, and a refused session push fails the command. #1291's session retry e2e now expects that (exit 1 while origin refuses, then Pushed: sessions/alice/2026-09.md). tsc --noEmit and lint pass. vitest run: 496 files, 12420 tests pass (21 skipped). e2e: cli-error-exit, reports-writer-sync-561, workflow-publish-resume and workflow-conformance pass (4 files, 53 tests).

Before that, at 988af80f, rebased onto main (with #1251, #1252, #1268 and #1281): tsc --noEmit, lint and build pass. vitest run: 495 files, 12397 tests pass (21 skipped). e2e, the full suite (the branch touches modules 146 of 147 files reference): 169 files and 1430 tests pass (30 skipped). workflow-publish-resume now has alice take back the run bob finished with her interrupted copy still dirty: resume --claim answers done and leaves the copy as it was. The two terminal Ctrl-C cases of workflow-signals fail here at the same setup wait as on main; CI runs them.

The rebase onto #1268 dropped the options update() passed to the worktree open, so a claim from a team with no teamai-reports created the branch on origin; update() passes them again, and workflow-handoff covers it. The last commit carries the Windows test-list fix main needs for codex-team-hooks.test.ts.

Real CLI, before the rebase (the first row at 622a1121, the rest at 5c3860eb; not rerun at 988af80f; dist/index.js, init --self --provider git with a forge URL mapped to local bare origins, two or three members each with their own HOME and data home, a bare team origin and a bare business origin, a stub claude that records the session it resumes):

Scenario Observed
alice's published run ends succeeded, a merge deletes teamai/<run>/* on the business origin, then bob, who never had the run, runs workflow resume <run> at 622a1121: done with succeeded, exit 0, bob owns the run at state revision 2. At 5c3860eb: commit_missing on teamai/<run>/base, exit 1
alice starts a run with a workspace: new copy, stops it mid-run, publishes; bob runs workflow resume <run> bob claims it, fetches the run's branches and drives it to succeeded; the copy branch on the business origin holds both members' commits; alice's publish then answers not_owner naming bob
A copy at the recorded commit with an untracked file left by an interrupted step, when the run comes back to that machine while it runs resume answers branch_diverged naming the worktree; the file never reaches the business origin
alice's first publish is refused by the team origin; she resumes and the run ends origin's snapshot shows succeeded; bob's workflow resume <run> runs nothing; the end record stays alice's
A copy push fails at the end of a published run done carries notPublished with commit_missing and the push to run; origin keeps the earlier snapshot
The process is killed after the run file saved its end, before the end was published the next workflow resume publishes it
A published run that ended is resumed after its teamai/<run>/* branches were deleted done, nothing published or pushed again
A cancelled published run is claimed, a step retried, then resumed the retried step runs as its next pass
alice ends a run bob claimed meanwhile alice is told bob owns it; the snapshot and end record on origin stay bob's
plan, build, check, final, each session: { from: plan }, alternating alice and bob with publish --sessions final resumes a session holding the plan, build and check turns; on one machine every step resumes the same session id
bob continues the session in a copy and publishes without --sessions; carol claims and publishes --sessions the publish succeeds, keeps alice's archived session and lists bob's under skipped
Publishing while the driver advanced the run 18 revisions succeeds, no state_moved
kill -TERM to the driver pid with a running command step, max_parallel: 1 the command and its child exit; workflow resume finishes the run
session save --push refused by the team origin, then retried the retry prints Pushed: sessions/alice/<month>.md
workflow resume --claim while this run's driver is running driver_running; teamai-reports on origin unchanged

Left to CI: Codex, CodeBuddy, OpenCode, and the gitlab/github providers. Windows signal handling was not run.

Merge Danger

Door: two-way. Run files gain optional fields (publication, sessionContinuations, and the session a step's lease offers); old run files read as before. The snapshot format is new.

Blast Radius: workflows and session commands. Runs that are never published behave as before, apart from the driver signal fix and the session command locking and exit codes.

Related: #1267, #1270, #1277 (found during this work, outside its scope). #1268 is the separate reports git timeout fix.

Closes #1084

@github-actions

Copy link
Copy Markdown

I couldn’t complete the exact-scope review: the checkout is shallow, and the requested three-dot diff fails with no merge base. GitHub access is also unavailable.

I did not substitute a two-commit diff, which would include unrelated changes, or run, build, or install PR code.

The supplied PR description documents sufficient testing, including representative real-CLI verification; no missing-e2e finding is warranted.

Please provide the exact diff or a checkout with the base history available. No code-review verdict is issued.

@SaulMoro
SaulMoro force-pushed the feat/1084-publish-resume branch from cd5ae1d to 5c3860e Compare October 22, 2026 06:04
@SaulMoro SaulMoro assigned jeff-r2026 and unassigned jeff-r2026 Oct 22, 2026
@github-actions

Copy link
Copy Markdown
  • [P1 blocking] Claiming a completed run still requires its deleted workspace branches — src/workflow/handoff.ts:647 unconditionally checks the business origin, including when the published snapshot is succeeded. If Alice finishes and publishes a workspace run, then deletes teamai/<run>/* after merging, Bob’s first workflow resume <run> fails with commit_missing instead of returning done. Skip workspace availability checks and reconciliation when claiming a successfully completed run; the existing deleted-branch test covers only the original owner.

The PR description documents sufficient testing, including representative real-CLI verification. No missing-e2e finding applies.

The earlier review’s shallow-history blocker is resolved: the requested three-dot diff is readable. I did not run, build, or install PR code.

A member can publish a run to teamai-reports and continue it on another machine, or hand it to a teammate, with its workspaces and, when asked, its agent sessions. The session commands now write teamai-reports under its lock with exit codes that say when nothing was written, and the local driver stops a command step when it alone gets SIGTERM.
…ss origin

A claim checked the run's branches on the business origin, and the local driver reconciled the copies once after it, whatever the run's status. After the owner finished a run and a merge deleted its teamai/<run>/* branches, another member's first resume failed with commit_missing instead of reporting how the run ended.

Only a running run needs its workspaces. A claim checks them only then, and the driver reconciles a claimed run's copies once a retry reopens it.
@SaulMoro
SaulMoro force-pushed the feat/1084-publish-resume branch from 622a112 to 988af80 Compare October 22, 2026 07:42
@SaulMoro SaulMoro changed the title [After #1251] feat(workflow): publish and resume workflow runs across machines (#1084) feat(workflow): publish and resume workflow runs across machines (#1084) Oct 22, 2026
@SaulMoro
SaulMoro marked this pull request as ready for review October 22, 2026 07:42
@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: The earlier completed-run claim bug is fixed. Business-origin checks and local-copy reconciliation now run only while the run is running, allowing finished runs to be claimed after branch deletion.
  • Testing sufficient: The description includes representative real-CLI verification. Those runs predate the head, but the trusted rules explicitly make that a note, not a blocking finding. Extra provider/agent coverage is deferred to CI.
  • Scope: The requested three-dot diff is readable. I did not run, build, or install PR code.

Keep this branch's reports publish contract over Tencent#1291's: a write that
returns null pushes nothing, an empty list retries the unpushed commit, and
a refused session push fails the command. Tencent#1291's session retry test now
expects that contract (exit 1 while origin refuses, then Pushed: <file>).
@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: The completed-run claim bug is fixed. Origin checks and local-copy reconciliation run only while the run is running, so finished runs can be claimed after branch deletion.
  • Testing sufficient: The description documents representative real-CLI verification. Older verification commits are a note, not a blocker under the trusted rules; additional providers and agents are deferred to CI.
  • Scope: Reviewed the requested three-dot diff against the base version’s review rules. I did not run, build, or install PR code.

teamai-ci added 4 commits October 23, 2026 07:26
Tencent#1084 promises that a published run snapshot leaves out "prompts, secrets,
unsafe outputs, and absolute machine paths", and that "snapshots contain no
secret, prompt, private session content, or absolute machine path". The
snapshot dropped the checkout and workspace owners, but copied inputs,
outputs, results, and HITL notes as they were, so an input such as
/Users/alice/private/data.csv reached teamai-reports.

The check that refuses a secret now also refuses a value or key holding an
absolute path of this machine, with local_path_detected naming the step and
field. It counts a Windows drive or share path, a ~/ path, a file:// URL,
and a / path whose first directory exists at this machine's root. A URL, a
relative path, a route such as /api/v1, and text such as and/or pass. The
value is not rewritten, since expressions read it.
The snapshot named its owner by the OS login, while the run records, labels,
and stats on teamai-reports name the member by the configured TeamAI
username. A run published by alice on a laptop whose login is a1234 showed
a1234 in the snapshot and in every not_owner message, and alice in the run
records. The owner now carries the username the run records use.
The snapshot check masked an environment value only when its name looked
secret, such as GITHUB_TOKEN. A secret the team declares in env/secrets.yaml
can have any name, so a run whose output held the value of WAREHOUSE_DSN was
published as it was.

collectTeamSecrets, next to resolveTeamEnv, returns the value of each
declared secret as this member resolves it, keyed by name, and publish
checks the snapshot against those values too. Plain env.yaml variables are
not secrets and still publish.
Run records follow the usage reporting setting, while workflow publish
writes the run's state with it on or off. That state is what another
machine needs to continue the run, not a usage report. The guide now says
so, and that a run stays off teamai-reports until it is published.
@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: The completed-run claim bug is fixed. Business-origin checks and copy reconciliation run only while the run is running, allowing finished runs to be claimed after branch deletion.
  • Testing sufficient: The PR description documents representative real-CLI verification. Older verification commits are a note, not a blocker under the trusted rules. Additional providers and agents are deferred to CI.
  • Scope: Reviewed the requested three-dot diff using the checked-out base version’s review rules. I did not run, build, or install PR code.

The failure-code test keeps both sides: main's namespace conflict
diagnostics and this branch's run handover answers.
@github-actions

Copy link
Copy Markdown
  • [P1 blocking] Short declared secrets can be published in plaintext — src/env-resolution.ts:339 drops declared secret values shorter than eight characters. Declare ACCESS_CODE in env/secrets.yaml, resolve it to 493827, and put that value in inputs.target: neither environment-name heuristics nor secret patterns catch it, so workflow publish writes it to teamai-reports. Explicitly declared secrets should not use the heuristic minimum-length cutoff.

Resolved: The earlier completed-run claim bug is fixed; finished runs skip origin checks and copy reconciliation.

Testing sufficient: The description includes representative real-CLI verification. Older verification commits are not blocking, and additional providers and agents are deferred to CI.

Reviewed the requested three-dot diff using the trusted base rules. I did not run, build, or install PR code.

publish dropped a value declared in env/secrets.yaml when it was shorter
than the 8 characters that mark an environment value as secret, so a
declared ACCESS_CODE=493827 in a run's inputs was published as is.

A declared value is now checked whatever its length. One shorter than 8
characters matches only as a whole word, so 4938 does not match inside
build-49381. One shorter than 4 cannot be told from ordinary text: it is
not checked, and publish warns with its name instead of dropping it
silently.
@github-actions

Copy link
Copy Markdown
  • [P1 blocking] Numeric declared secrets bypass publication checks — src/workflow/snapshot.ts:355 checks only strings and skips numeric primitives at line 366. Declare ACCESS_CODE=493827 in env/secrets.yaml and have a step output {"code":493827}: workflow publish writes the secret unchanged to teamai-reports, although "493827" would be refused. Check numeric values against resolved declared secrets before publishing.

Resolved: The completed-run claim bug is fixed. The earlier six-character secret example is also fixed when represented as a string.

Testing sufficient: The description documents representative real-CLI verification. Older verification commits are not blocking; additional providers and agents are deferred to CI.

Reviewed the requested three-dot diff using the trusted base review rules. I did not run, build, or install PR code.

publish checked only strings and keys, so a step output {"code":493827}
with a declared ACCESS_CODE=493827 was published as is, while "493827"
was refused. A number or boolean is now checked as its JSON text, by the
same secret and path checks as a string.
@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: Finished-run claims skip business-origin checks and copy reconciliation, allowing claims after branch deletion.
  • Resolved: The earlier six-character declared-secret example is rejected as both a string and a numeric output.
  • Testing sufficient: The description documents representative real-CLI verification. Older verification commits are a note, not a blocker; additional providers and agents are deferred to CI.

Reviewed the requested three-dot diff using the trusted base review rules. I did not run, build, or install PR code.

Keeps main's migration results and archive lock ownership, with session
migrate --push archiving through teamai-reports on top: the archive phase
returns its failures as migration results. The local driver test awaits
saveSession, which main made asynchronous.
@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: Finished-run claims skip business-origin checks and copy reconciliation, allowing claims after branch deletion.
  • Resolved: The earlier six-character declared-secret examples are rejected as both strings and numeric outputs.
  • Testing sufficient: The PR description documents representative real-CLI verification. Older verification commits are not blocking under the trusted rules; additional providers and agents are deferred to CI.

Reviewed the requested three-dot diff using the trusted base review rules. I did not run, build, or install PR code.

# Conflicts:
#	docs/guide/dashboard.md
#	docs/guide/zh-CN/dashboard.md
#	src/session-flow/session-cmd.ts
#	src/session-flow/session-migrate-cmd.ts
@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: Finished-run claims skip business-origin checks and copy reconciliation, allowing claims after branch deletion.
  • Resolved: The earlier six-character declared-secret examples are rejected as both strings and numeric outputs.
  • Testing sufficient: The PR description includes representative real-CLI verification. Older verification commits are not blocking under the trusted rules; additional providers and agents are deferred to CI.

Reviewed the requested three-dot diff using the trusted base review rules. I did not run, build, or install PR code.

@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: Finished-run claims skip business-origin checks and copy reconciliation, allowing claims after branch deletion.
  • Resolved: The earlier six-character declared-secret examples are rejected as both strings and numeric outputs.
  • Testing sufficient: The description documents representative real-CLI verification. Older verification commits are not blocking under the trusted rules; additional providers and agents are deferred to CI.

Reviewed only the requested three-dot diff against the trusted base review rules. I did not run, build, or install PR code.

# Conflicts:
#	src/workflow-commands.ts
@github-actions

Copy link
Copy Markdown

No new findings I’m confident are real in the current diff.

  • Resolved: Finished-run claims skip business-origin checks and copy reconciliation, allowing claims after branch deletion.
  • Resolved: The earlier six-character declared-secret examples are rejected as both strings and numeric outputs.
  • Testing sufficient: The PR description documents representative real-CLI verification. Older verification commits are not blocking under the trusted rules; additional providers and agents are deferred to CI.

Reviewed the requested three-dot diff against the trusted base review rules. I did not run, build, or install PR code.

@jeff-r2026 jeff-r2026 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verified head e70a333 merged onto main a890d96: tsc, lint, build pass; workflow/redact/git-kind-reports unit tests 1424/1424; workflow E2E 50/55, the 5 workflow-signals failures reproduce identically on plain main in the test container and pass in CI. Codex: no new findings. CI green.

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.

[feat] Publish and resume complete workflow state across machines

2 participants