Repository navigation
v4.0.0: events, minions, and trackers other than GitHub - #40
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…racker, labels map ScmPort is now TrackerPort & CodeHostPort. Every new GitHub() in the CLI and the dashboard goes through makeScm(config), which pairs config.tracker (github or http, Tracker API v1) with GitHub as the code host and applies config.labels at the tracker boundary. With a non-GitHub tracker the PR is found by head branch, closing keywords are rewritten, the PR URL is commented on the tracker issue and a merge closes it. Doctor reports the tracker kind and its auth. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
core/event.ts holds the envelope, EVENT_TYPES and the x-kaas-signature HMAC. engine/bus.ts writes each emit to a SQLite outbox and delivers it to config.events.sinks with exponential backoff. runWorkflow, the pr step, processReadyIssue and both merge paths emit through emitEvent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tations MemoryTracker and a Bun.serve reference server in tests/fixtures; one TrackerPort contract run against both; code, server and docs routes held equal; branch-mode linking and an e2e pickup on the http tracker. Two mutations (bearer header, closing-keyword rewrite). Docs and the config example name tracker and labels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An adapter may not import another adapter (tests/hexagon.test.ts); the resolver composes the GitHub and http adapters, so it lives beside github.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
POST /events takes HMAC-signed CloudEvents from other KaaS apps (only external types), deduped on id. A workflow's `on: event:` files a ready issue per event; `.factory/minions/*.yml` are checked at boot and run with no issue and no PR, emitting factory.minion.completed and their own type. `factory minion list|run` and `factory events tail|replay`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…runs Another app's event (inbound, or a minion's answer) files its issue with no factory:ready, so a maintainer labels it and pickup checks their role. A minion respects paused intake and the repo and machine daily caps through one resolver (spendCapHit, shared with the poll), records spend on the shared ledger, runs with triage's tools and allow-list, and gets the event fenced as untrusted data. Mutations for the signature, inbound and each of these. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every external event wakes the poll, which applies the label path's trust gate, intake and caps; no code reads an issue or actor from event data. A test posts a correctly signed event naming an issue an untrusted user labelled ready and asserts nothing runs, with mutations for both paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
resumeInReview only looked at a PR's merge under merge.policy auto or dry-run, and findPrByHead lists open PRs only. A PR a human merged on GitHub with policy off (the default) left an http tracker's issue open in factory:in-review forever, and factory.pr.merged and the merged retro never fired on any tracker. - CodeHostPort.mergedPrByHead: the newest merged PR on a head (gh pr list --state merged), passed through ComposedScm with branch-mode linking. - resumeInReview checks it first: a merged PR closes the issue, takes in-review off, emits factory.pr.merged by "human", runs the retro and returns "shipped". A `<!-- factory:merged pr=N -->` comment makes it once per PR; a PR closed without merging does nothing. - The factory's own merge goes through the same recordMerge (by "factory"), so a later poll never reads it back as a human merge. - docs/events.md and docs/tracker-api.md say what the code does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The spend ledger comment showed the worker id (hostname and pid) and dollar totals on customer-facing tracker cards, and the budget park comment showed the spend amounts. Both now show neutral text; the numbers stay in the hidden markers the factory reads back. FakeGitHub and MemoryTracker now refuse any write whose visible text has the host name, a .local host, a dollar amount or "model". tests/tracker-comments walks every tracker write call site in src/ and pins the test that drives it through one of those fakes. Four new mutations cover the checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#42) Verify could not check "removing the guard makes the tests fail": its Edit on the issue worktree is denied, so kaas-suite card 15 parked as uncertain twice. template/.factory/mutate.sh copies HEAD's tree to a temp dir, runs the named tests there unmutated and then with one literal replacement, prints a MUTATION: line, appends the result to proof.json, and deletes the copy. The worktree never changes. What runs is fixed by the script and config: the test gate's cmd as argv on named test files, a source target outside .factory/.claude/protected/build files, a replacement from a fixed operator list, a minimal env, and dependency dirs copied rather than linked. Verify's allow-list gains the script; its only Edit rule stays the run dir. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
listPrs now asks gh for isCrossRepository and drops PRs from other repositories. Every lookup by head branch or by issue goes through it, so a fork can no longer pass as the factory's PR by naming its branch factory/issue-N or writing "Closes #N" in its body. A test and a mutation pin the filter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A runner that cannot start, exits 126/127 or is killed, a timeout, a non-zero exit with no failed test (a crash or compile error), a no-op replacement, and any unexpected exception are status=error, exit 2, never bites or survives. The fixture repo disables git gc and maintenance so a background run cannot touch .git while the tree is hashed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n sets) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d mutation sets) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(watch): notice a PR a human merged, whatever merge.policy says
Keep operator detail out of tracker comments (#44)
Ignore pull requests from forks when finding the factory's own PR
fix(verify): run a plan's mutation on a throwaway copy with mutate.sh (#42)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Events, minions and the tracker split. See CHANGELOG.md v4.0.0 and research/v4/PLAN.md for the plan.
POST /eventsthat only wakes the poll,on: eventworkflows.TrackerPort/CodeHostPortsplit;httptracker speaking Tracker API v1 (docs/tracker-api.md);labelsmapping.Gate:
make check1684 pass, 0 fail (was 1593).🤖 Generated with Claude Code