Skip to content

23 markletree - #53

Merged
SaifRehman merged 42 commits into
mainfrom
23_markletree
May 18, 2026
Merged

23 markletree#53
SaifRehman merged 42 commits into
mainfrom
23_markletree

Conversation

@SaifRehman

Copy link
Copy Markdown
Contributor

No description provided.

SaifRehman and others added 30 commits May 16, 2026 20:18
… + 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)
…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>
SaifRehman and others added 10 commits May 18, 2026 02:29
…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>
Comment thread agentfm-python/tests/unit/test_peers.py Dismissed
Comment thread agentfm-python/tests/unit/test_reputation.py Dismissed
SaifRehman and others added 2 commits May 18, 2026 14:45
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>
@SaifRehman
SaifRehman merged commit 26b1495 into main May 18, 2026
2 of 10 checks passed
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.

1 participant