Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
778b67b
A person's Stop stays stopped until a person starts it (#2335)
santoshkumarradha Nov 4, 2026
0982bf6
A repository with no factory file starts quietly, and a job's rules a…
santoshkumarradha Nov 4, 2026
30a3400
Factory: a job that has not worked reads its issue instead of repeati…
santoshkumarradha Nov 4, 2026
94ca31d
Owed checks name the tool, not a machine's path (#2322)
santoshkumarradha Nov 4, 2026
22d06d4
Publish anyway: a person ships past correctly skipped checks (#2323)
santoshkumarradha Nov 4, 2026
419631c
Take tests judge rows only after the take starts (#2340)
santoshkumarradha Nov 4, 2026
57a8593
factory: shipped steps carry short engineering methods (#2286)
santoshkumarradha Nov 4, 2026
c50abac
A running step's chat streams like the manager's (#2329)
santoshkumarradha Nov 4, 2026
012b87c
Other computers list more of this one's chats, sooner, and say how ma…
ZeroPoint95 Nov 4, 2026
8dc722d
docs: name pull request 2341 in its change entry (#2344)
santoshkumarradha Nov 4, 2026
a3ae454
Test runner names a shard mismatch instead of exiting silently (#2345)
santoshkumarradha Nov 4, 2026
0f8574e
A take no longer loses or double-counts cost (#2332)
santoshkumarradha Nov 4, 2026
59cdf22
Memory off skips the job marking, and the marking seeks by session (#…
santoshkumarradha Nov 4, 2026
d35a0dc
Moving a chat says how far it has got, stops when stalled, and can be…
ZeroPoint95 Nov 4, 2026
1f1a733
Agent spend is complete: agents.open and agent.changed carry the save…
AbirAbbas Nov 4, 2026
4d6562c
Merge app/v3 into workstreams/main
AbirAbbas Nov 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions PERF.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,25 @@ always coordinate through it, so no build leaves it out. On linux/amd64 it adds
3,379,200 bytes to the stripped binary (75,755,785 to 79,134,985 on the same dev
base), and the cap moves by the same amount, from 75,811,848 to 79,191,048, so
the 56,063 bytes of headroom the base had are kept.

## Usage writer identity startup

`TestUsageMillionRowLedgerFlush` constructs 1,000,000 unique historical call
identities in 185,000,000 bytes before measuring the public writer. Initialization
streams valid full rows and retains their identities rather than a decoded row
slice. Enqueue through flush has a 256 MiB allocation budget. The existing
two-second flush contract must complete the new $0.002 call; replaying that call
and historical identities adds no rows. An independent public ledger walk checks
1,000,001 records, exact consumed bytes and $1000.002 total after the measurement.
Elapsed times are diagnostic. The retained identity set still grows with history.


## Usage writer overflow draining

`BenchmarkLedgerWriter20K` times 20,000 distinct charges from `RecordUsage` to
the last completed writer callback. Outside the timer it checks the flush,
20,000 public ledger rows, $200 total and no drops. Compare the same harness
on both revisions, with and without race instrumentation; run with `-run '^$'`.
The writer batches at most 128 already admitted rows per ledger lock. A quiet
queue flushes immediately, and flush/close barriers follow completed writes.
Identity generation checks and duplicate suppression still run under that lock.
34 changes: 32 additions & 2 deletions cmd/codeaf/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func runApp(args []string) error {
backend.turnLong = *turnLong
}
defer backend.watchSpendRows()()
defer backend.watchAgentSpend()()
// The crews are watched from the start: a manager's start or a member
// woken by its manager must not wait for the window to ask for crews.
backend.memoryStore = func() (*store.Store, error) {
Expand Down Expand Up @@ -588,6 +589,9 @@ type appBackend struct {
// stopProgress the factory runner's progress news (appfactory_progress.go).
stopPhases func()
stopProgress func()
// stopStages and stepStreams: the factory steps' events (appfactory_stepstream.go).
stopStages func()
stepStreams map[string]*appStepStream
// briefs takes the progress news of this machine's factory's jobs as
// writes of their briefs (appfactory_brief_writer.go).
briefs *briefDebounce
Expand Down Expand Up @@ -629,8 +633,8 @@ type appBackend struct {
turns atomic.Uint64
assembled atomic.Bool

// unreadSay is held from working an agent's unread out to saying it,
// so the last unread the window hears is the last one worked out
// unreadSay is held from working an agent's unread and saved spend out
// to saying them, so the last readings the window hears are the latest
// (appunread.go). It is taken before mu and the app file's lock, never
// under them.
unreadSay sync.Mutex
Expand Down Expand Up @@ -730,6 +734,9 @@ type appBackend struct {
// spendRowsPending holds one read of today's figure for rows written
// together (watchSpendRows).
spendRowsPending atomic.Bool
// spendRestates hands saved-spend news off without taking mu or waiting
// for the window (appspendsaved.go).
spendRestates appSpendRestates
// turnLong is how long a reply runs before turn.long ([appTurnLong]).
turnLong time.Duration
// inbox is every open ask as one list (appinbox.go); emit is its tap.
Expand Down Expand Up @@ -776,6 +783,10 @@ type appAgent struct {
repliedAt time.Time
askedElsewhere time.Time
saidUnread bool
// saidSpend is the saved figure last said in a dressed open/list answer or
// agent.changed, never a cache for a later view. mu guards it; unreadSay
// orders sayings.
saidSpend float64

// listening is when this light record began watching crew traffic.
listening time.Time
Expand Down Expand Up @@ -1052,6 +1063,7 @@ func newAppBackend(emit appwire.Emitter, open appOpener) *appBackend {
b.stopPhases = b.listenPhases()
b.briefs = newBriefDebounce(appBriefDebounce, b.writeBriefLater)
b.stopProgress = b.listenProgress()
b.stopStages = b.listenStages()
guard.Go("app/sweep", b.sweep)
b.startLocalChatPublication()
return b
Expand Down Expand Up @@ -1738,6 +1750,7 @@ func (b *appBackend) openAgent(id string, warm bool) (appwire.Agent, error) {
}
})
if busy {
view.SpentUSD = b.savedSpendOf(view.ID)
return view, nil
}
a.gate.Lock()
Expand Down Expand Up @@ -3037,6 +3050,20 @@ func appUserEntryID(n int) string { return "u" + strconv.Itoa(n) }

func appAnswerEntryID(n, m int) string { return "a" + strconv.Itoa(n) + "." + strconv.Itoa(m) }

// appEntryMessage is the person's message an entry id of those two is under.
func appEntryMessage(id string) (n int, ok bool) {
at, found := strings.CutPrefix(id, "u")
if !found {
answer, isAnswer := strings.CutPrefix(id, "a")
at, _, found = strings.Cut(answer, ".")
if !isAnswer {
return 0, false
}
}
n, err := strconv.Atoi(at)
return n, found && err == nil
}

func appToolEntryID(call string) string { return "t" + call }

func appNoteEntryID(n, k int) string { return "n" + strconv.Itoa(n) + "." + strconv.Itoa(k) }
Expand Down Expand Up @@ -4580,6 +4607,9 @@ func (b *appBackend) Close() error {
if b.stopPhases != nil {
b.stopPhases()
}
if b.stopStages != nil {
b.stopStages()
}
if b.stopProgress != nil {
b.stopProgress()
}
Expand Down
Loading
Loading