23 markletree - #53
Merged
Merged
Conversation
… + TUI peer-view) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…carry voting weight - bossbootstrap.go: use node.Host.ID().String() (base58) instead of string(node.Host.ID()) (raw bytes) when constructing the self-seed - eigentrust.go: convert RaterPeerId/SubjectPeerId bytes to base58 via peer.ID().String() so inbox entries and seeds share the same key space - api_reputation.go: use subjectStr (base58) when calling engine.Score() - eigentrust_test.go: update all Seed/Score call sites to use .String() - testutil/ledger.go: add OpenTestStore and AppendOwnRating helpers - bossbootstrap_test.go: new failing-then-passing regression test Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mage, capability, honesty, equivocator, dispatch_allowed)
…GatherPeerEntries helper
…view
Defect 1: /v1/peers/{id}/log?limit=600 was resetting to 50 instead of
capping at 500. Fixed by separating the zero-check from the cap check.
Defect 2: handlePeerGet called GatherPeerEntries(ctx, store, pid, 0)
expecting uncapped behavior, but GatherPeerEntries was defaulting 0 to 50.
Fixed by treating limit<=0 as "unbounded" in GatherPeerEntries, letting
only the slicing guard apply the cap.
Also fixed test hash collision bug in peer_view_test.go where pvInsertSeq
byte overflow caused duplicate hashes after 256 insertions.
Tests added:
- TestHandlePeerLog_LimitCapAt500: verifies HTTP handler caps at 500
- TestGatherPeerEntries_UncappedScan: verifies limit=0 returns all entries
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d; cleanup
Important fix 1: Move bytesEqualPB from api_reputation.go to peer_view.go so
peer_view.go becomes self-contained. Both files are in the same package and
api_reputation.go uses the function via the peer_view module.
Important fix 2: Rename misleading 'count' field in /v1/peers/{id}/log response
to 'returned' to clarify it represents the number of entries in the current batch,
not the total. This makes pagination semantics clear: clients now see exactly how
many entries were returned in this batch (especially important when limit+offset > total).
Cleanup 1: Remove stale 'var _ = store.KindRating' anchor from api_reputation.go
— the store package is already used directly via s.IterateAllOwnEntries.
Cleanup 2: Run gofmt on modified files.
Also updated TestHandlePeerLog_RaterStatus to check for 'returned' instead of 'count'.
All tests pass; no compile errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…, capped at +/-0.5/hr per peer Implements Phase 2 / Task 2.1 of the v1.3.1 trust layer. Workers earn or lose reputation automatically on each dispatch: +0.1 per success, -0.1 per failure, aggregated per peer per hour and written as a single signed Rating entry in the boss's own ledger. The net score is capped at ±0.5/hr to prevent retry-loop trust manufacturing. Net-zero windows (equal successes/failures) skip the ledger write. The ticker runs as a background goroutine started from bossbootstrap; all dispatch handlers (handleExecuteTask, handleChatCompletions, streamChatCompletion, handleCompletions, streamTextCompletion) are wired with nil-guarded RecordOutcome calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ledger; auto-gossipped Replace the ephemeral libp2p stream in handleFeedbackLoop with two ledger appends via appendFeedbackComment. Boss now stores the comment body in the content-addressed comments store and appends a pb.Comment (and optionally a pb.Rating with dimension="honesty") to the Merkle ledger, which gossips both entries automatically via the existing subscribe loop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add Feedback and FeedbackRating fields to ExecuteRequest. After a successful task stream, if req.Feedback is non-empty and the trust layer is wired (completionRater != nil), the handler calls appendFeedbackComment best-effort — a failure only emits a slog.Warn and does not affect the HTTP response. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ext feedback.log writer Delete handleFeedbackStream (plaintext JSON → feedback.log), remove the SetStreamHandler(FeedbackProtocol) call from Worker.Start, and drop the two tests that exercised the old handler. Add TestWorker_NoLongerHandlesFeedbackProtocol which asserts that opening a stream on FeedbackProtocol to an un-Started worker returns an error — confirming the protocol is no longer registered. FeedbackProtocol constant is preserved for Phase 8 cleanup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…to-serves LedgerFetchProtocol Wire ledger.NewWithOptions into cmd/relay/main.go so every relay automatically becomes a persistent archive of FeedbackTopic and EquivocationTopic entries, served via LedgerFetchProtocol. Add TestRelay_ArchivesGossippedEntries which verifies that a gossipped Rating lands in the relay's SQLite inbox_entries within 8s. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…es entries against relay head - Add AcceptEntry(ctx, []byte) and LastInboxIdx(ctx) to the Ledger interface; implement both on ledgerImpl. - Add HeadFetchProtocol (/agentfm/head-fetch/1.0.0): tiny server-side handler on ledgerImpl that streams the current signed LogHead; FetchRemoteHead client in catchup.go. - Add VerifyHeadSignature(head) exported helper (reuses verifyHeadSig). - CatchUp(ctx, local, host, relayPID): pulls relay entries the boss missed while offline, verifies each against the relay's signed head tree_size boundary, routes through AcceptEntry (sig-verify + dedup). - bossbootstrap.go: spawn catch-up goroutine after ledger open; waits up to 30s for relay connectivity, non-fatal on failure. - catchup_test.go: 4 tests (happy-path 3-entry pull, no-op on empty relay, idempotency on second call, VerifyHeadSignature valid/invalid). - Update stubLedger in boss tests and ledger_test.go contract check for the two new interface methods. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Scans both own-log (entries) and inbox (inbox_entries) payloads to collect every distinct SubjectPeerId, deduplicating across both tables. Also adds testutil.AppendInboxRating mirror of AppendOwnRating. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds KnownPeer struct and Boss.ListKnownPeers method that merges in-memory activeWorkers (online) with store.DistinctSubjects (offline/never-seen-alive), sorted online-first then by LastSeen desc. Also adds HostForTest export. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends handleGetWorkers to accept ?include_offline=true, returning peers known only via ledger entries alongside online peers. Response always includes online_count and offline_count for operator dashboards. Backwards compatible: without the query param only online peers are returned. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ack) with reputation-aware dispatch badge - Refactors executeFlow into a loop with showPeerMenu (pterm select or test hook) and executeTaskFlow (existing task path, unchanged). - Adds shortDigest, reputation floor check, and dispatch badge to the agent-info box shown before the menu. - Adds Boss.menuPickerForTest / SetMenuPickerForTest and Boss.peerViewHookForTest / SetPeerViewHookForTest for deterministic unit testing without a terminal. - Adds Boss.reputationFloor field (Phase 8 wires the production value). - Adds RenderRadarForTest(io.Writer) to testing.go. - Adds viewPeerHistory, renderPeerView, RenderPeerView, and formatting helpers (compactAge, truncateStr, nonEmpty, formatScore, formatEquiv) to peer_view.go for use by executeFlow and the E2E test. - Adds renderRadar (ONLINE/OFFLINE two-section render) to ui.go. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ed] rater tags - Adds TestRenderPeerView_RendersRatingScore: verifies rating score appears in rendered output. - Adds TestRenderPeerView_TagsUnverifiedRaters: verifies raters with honesty score < 0.1 (or no reputation engine) are tagged [unverified]. - Adds TestRenderPeerView_NoEntries: verifies empty-state message shown. - Adds TestRenderPeerView_HeaderContainsPeerID: verifies short peer ID in header. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…y peer - Adds renderRadar(ctx, io.Writer) to ui.go: partitions ListKnownPeers into ONLINE and OFFLINE sections with honesty scores and equivocator tags. Both sections are navigable via the flat displayList in the interactive radar. - Adds RenderRadarForTest(io.Writer) to testing.go for headless tests. - Adds TestRadarRender_ShowsOnlineAndOfflineSections: asserts both section headers appear when one online + one offline peer is known. - Adds TestRadarRender_OnlineSectionShowsPeer: asserts short peer ID appears in render output. - Adds TestRadarRender_EmptyMesh: asserts both labels present when no peers are known. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…istance) Replace per-edge accumulation with per-(rater,subject) weighted-mean so a rater's total influence on a single subject is bounded to one vote regardless of how many edges it submits, closing the Sybil-flood vulnerability. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…; replaces checkAttestation Add trust_gate.go with checkTrust (equivocator + floor checks), replace pickWorker's checkAttestation/writeAttestationRating call with checkTrust, add reputationEngineIface to avoid nil-pointer gotcha, add Options.ReputationFloor, add SetLedger/WithReputationFloor/SetReputationScoreForTest test helpers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…aced by checkTrust) Remove attestation/trustedagents infrastructure: delete attest.go, attest_test.go, internal/trustedagents/, purge AttestationMode/TrustedAgents/ RejectUnknownImages from Boss struct and Options, update bossbootstrap and CLI to accept --reputation-floor instead of the old attestation flags. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…or P2P agent state) The internal/rekor package was a stub from the start and never tracked in git. It has zero production importers. Verified with grep; go build continues to pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…estTrustEndToEnd is GREEN - Remove FeedbackProtocol references from worker/handler_test.go and feedback_schema_test.go (inline string literal; constant is gitignored) - Add Store() to Ledger interface and ledgerImpl; expose SetReadStoreForTest and SetLedger test hooks on Boss - Add stubLedger.Store() to api_reputation_test to satisfy updated interface - Add trust_e2e_helpers_test.go: openTestLedger + newSignedRating package-local helpers (avoid import cycle via testutil) - Rewrite trust_end_to_end_test.go: 2-host direct gossip design (no relay CatchUp needed); waits on InboxHas; green in 2.45s - Fix pre-existing pterm SpinnerPrinter race: handleExecuteTask now calls dialWorkerStream (spinner-free) instead of dialOmni in the HTTP path go test -tags trust_e2e -run TestTrustEndToEnd ./test/integration/ PASS (2.45s) go test -race ./... PASS — no data races Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ng v1.3.1 HTTP endpoints Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…guage; final E2E green Replace v1.3 allow-list / attestation-mode pitch with v1.3.1 reputation-driven trust model across README, docs/trust.md, and docs/cli.md. Remove --attestation-mode, --reject-unknown-images, --trusted-agents, --witness-threshold, --witness-set flags from the CLI reference; add --reputation-floor. Rewrite trust.md to describe the two-check dispatch gate, hourly aggregate ratings, relay archive, boss auto catch-up, TUI peer-view, EigenTrust normalization, and honest limits. Fix stale --attestation-mode comment in internal/types/types.go. All Go packages green (go test ./..., go test -race ./..., TestTrustEndToEnd). 200 Python tests green. Zero orphaned references in production code or docs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Options.ReputationFloor changes from float64 to *float64 so a nil pointer
unambiguously means "operator did not configure a floor" (NewWithOptions
defaults to -1.0 = allow all) and a non-nil pointer is used as-is —
including *ReputationFloor == 0 which now correctly means "refuse anyone
with a negative honesty score."
Previously every call site had an `if floor == 0 { floor = -1.0 }`
sentinel that conflated the zero-value with "unconfigured." An operator
who explicitly passed --reputation-floor=0 got the opposite of the
intended behavior. Sentinel removed from trust_gate.go, execute.go,
peer_view.go; resolution happens once in NewWithOptions.
Regression tests:
- TestCheckTrust_ExplicitZeroFloorRefusesNegativeScores
- TestCheckTrust_NilFloorOptionDefaultsToAllowAll
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The server-side witness role (witness.New(...).Start()) is never instantiated by any production binary. ledgerImpl.PublishAlert only existed to satisfy witness.AlertPublisher and has no other callers. Wire helpers moved to client.go so the consumer side stays intact. The receiving half of equivocation detection (runEquivSubscriber + acceptLocalAlert + permanent equivocators table) is unaffected — alerts arriving on agentfm-equivocation-v1 are still processed and peers still get floored at -1.0. Integration tests equivocation_test.go and witness_gather_test.go also removed (both tested server-side behaviour). Helper functions (mintKeyP2, freshSimpleRating) preserved in helpers_test.go for ledger_fetch and api_reputation_live tests that depended on them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The witness gather path in ledger.Append (attachWitnessSigs + proofForWitness + recordWitnessAck) ran on every append but short-circuited at empty witness peer list — pure no-op. Removed together with the supporting fields (witnessClient, witnesses, witnessAckMu, witnessAck), config type (WitnessSet), and the Witnesses field from Options. alert_test.go updated to drop the now-removed witnessAck field from the ledgerImpl literal. v1.3.2 will re-add this surface alongside operator wiring (--witness-threshold/--witness-set flags) and the witness server. The git history preserves the full implementation for reference. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rters) After removing the gather plumbing in the previous commit, nothing in the codebase imports agentfm/internal/witness or agentfm/internal/witness/pb. Deleted client.go, the pb/ generated file, and the proto/agentfm/witness/ source definition. v1.3.2 will re-add this surface alongside operator wiring (--witness-threshold/--witness-set flags) and the witness server. The git history at the prior two commits contains the full implementation for reference. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
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.
No description provided.