Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
484 commits
Select commit Hold shift + click to select a range
79b7622
Keep an allow-listed copy of a program's ending data in its action log
santoshkumarradha Oct 16, 2026
55b7b42
Keep senior-dev's claim and check in the ending; reject null and malf…
santoshkumarradha Oct 16, 2026
69f6fb1
Hold the ending's cap to the file's bytes and reject half-empty facts
santoshkumarradha Oct 16, 2026
026f79b
Read an ending's hunt coverage by sec's own rules and never rewrite a…
santoshkumarradha Oct 16, 2026
44e1c5a
Say nothing_to_audit as a true-only fact in sec's no-change ending
santoshkumarradha Oct 16, 2026
f6be022
Join a program child host watcher before returning
santoshkumarradha Oct 16, 2026
f59eeb3
Bound the host watcher regression body handshake
santoshkumarradha Oct 16, 2026
cc63fe6
app: add bounded read-only teams overview pages
santoshkumarradha Oct 16, 2026
96d0180
Merge current app branch while retaining durable delayed team starts
santoshkumarradha Oct 16, 2026
a726014
Arm the missing-key crew fixture before its first open
santoshkumarradha Oct 16, 2026
e515d17
Carry a specialist's stages, actions and ending on the app task page
santoshkumarradha Oct 16, 2026
837b82f
Tie a program's ending and last stage to its current process; bound t…
santoshkumarradha Oct 16, 2026
271b156
Tie a program's lines to the launch that wrote them, never to a time
santoshkumarradha Oct 16, 2026
916f3f7
Read a program's current launch within a budget and page every action
santoshkumarradha Oct 16, 2026
f8d0934
Keep every ending fact and read-state promise on the program wire
santoshkumarradha Oct 16, 2026
ec82032
Bound program metadata reads and reject special files before opening …
santoshkumarradha Oct 16, 2026
450d221
Bound every program record read and carry no window from a stopped read
santoshkumarradha Oct 16, 2026
5063a9b
Size the program record cap to a whole hello so no record codeaf wrot…
santoshkumarradha Oct 16, 2026
b49fe55
State the program metadata budget honestly for escaped producer records
santoshkumarradha Oct 16, 2026
6871cac
Clear exited programs before waiting for their late receipts
santoshkumarradha Oct 16, 2026
ecf2a1d
Read the workspace checkout's status over the app wire, and state tha…
santoshkumarradha Oct 16, 2026
de04eb1
Blank required on every filter driver, drop cut rename records, and l…
santoshkumarradha Oct 16, 2026
b4b54e0
Count lines of tracked checkout entries from diff-index, never open u…
santoshkumarradha Oct 16, 2026
05f818a
Run checkout count and attribute commands at the repository root
santoshkumarradha Oct 16, 2026
5696789
Land a conversation's own task branch only on a bound, revalidated plan
santoshkumarradha Oct 16, 2026
efeb4dd
Serve branches.land.plan and branches.land, and run no unnamed progra…
santoshkumarradha Oct 16, 2026
b1d9ae7
Ask a land's repository root through its bounded, stripped reader
santoshkumarradha Oct 16, 2026
83c0fa6
Report the actual native-confirmed Land producer in checkout status
santoshkumarradha Oct 16, 2026
f0d5637
Keep each conversation's process history one bounded record per job
santoshkumarradha Oct 16, 2026
b7ba6e8
HELD: serve processes.page and processes.log on the app wire
santoshkumarradha Oct 16, 2026
e0e67e4
Bound every process history read and fold, and read only managed logs
santoshkumarradha Oct 16, 2026
4605f89
Say the process history's corrected bounds in the protocol and change…
santoshkumarradha Oct 16, 2026
702448b
Never answer a live process twice, rebuild only a broken head, cut pa…
santoshkumarradha Oct 16, 2026
05c0c0a
Count every service, live and saved process against one page's limit …
santoshkumarradha Oct 16, 2026
2734d1a
Refuse to page an engine that cannot, read no tail for a paged servic…
santoshkumarradha Oct 16, 2026
b82482a
Serialize the process admission test spy captures
santoshkumarradha Oct 16, 2026
968df7c
Wait for the stopped service event before testing removed output
santoshkumarradha Oct 16, 2026
af639aa
Start a task, a program or a memory line through typed idempotent act…
santoshkumarradha Oct 16, 2026
5cbc945
Prove session actions across a real restart and offer only what a far…
santoshkumarradha Oct 16, 2026
8831062
Report where a memory line holds and sync a new claims folder before …
santoshkumarradha Oct 16, 2026
78d9fd5
Hold the widened-reach words to the producer's source and state the d…
santoshkumarradha Oct 16, 2026
e62c496
State a memory line's scope only where the method fixes it and sync t…
santoshkumarradha Oct 16, 2026
d1eac66
Say what a project replay carries and that Windows claims a process c…
santoshkumarradha Oct 16, 2026
d13c2c7
Say a Windows folder sync makes nothing durable rather than that it d…
santoshkumarradha Oct 16, 2026
48da799
Review and locate one checkout status row by its root-relative path
santoshkumarradha Oct 16, 2026
6c6b8b2
Refuse a duplicate path as ambiguous, label deletions from the row, c…
santoshkumarradha Oct 16, 2026
f7ddaa5
Clear computed hunks and counts when a checkout diff fails after prod…
santoshkumarradha Oct 16, 2026
e2e4d47
Never offer the remaining file of a deleted checkout row for Open or …
santoshkumarradha Oct 16, 2026
c4574de
Serve a crew's and all crews' recorded process history, read by pinne…
santoshkumarradha Oct 16, 2026
db1dfee
Name only verified recorded files, bound the whole encoded crew reply…
santoshkumarradha Oct 16, 2026
1f3be5b
Restore only a failed crew page's progress, remove a failed first pag…
santoshkumarradha Oct 17, 2026
dc14445
Install the render notifier at construction, not on the first render
santoshkumarradha Oct 16, 2026
7fca42f
Record every paid image request as an attempt in the render ledger
santoshkumarradha Oct 16, 2026
7b80237
Carry media_attempt on the tool result occurrence to the app
santoshkumarradha Oct 16, 2026
060a456
Release an image attempt's context with a named cause
santoshkumarradha Oct 16, 2026
c952b6b
Document image attempts, their stop and media_attempt
santoshkumarradha Oct 16, 2026
6750557
Keep a saved harness's pictures working: no ledger means no record
santoshkumarradha Oct 16, 2026
c41dc91
Keep the render ledger open across a stop-work round
santoshkumarradha Oct 16, 2026
5b3da7b
Surface a failed re-read in an image cancel instead of an empty record
santoshkumarradha Oct 16, 2026
b541943
Keep a task note's opaque client id on the page, the event and the pe…
santoshkumarradha Oct 16, 2026
3f52aab
Match a sent note's read receipt by its client id, and share the mess…
santoshkumarradha Oct 16, 2026
90246ae
Reserve opaque note correlation on the actual spoken source
santoshkumarradha Oct 16, 2026
4c54d0d
Write a task note's client id onto its direction in the admission tha…
santoshkumarradha Oct 17, 2026
b846804
Cover a delivered brief with failed page metadata and restored note keys
santoshkumarradha Oct 17, 2026
e129944
Commit a person note's client id in the same SQLite transaction as th…
santoshkumarradha Oct 17, 2026
704d0e8
Cover exact note-key bounds on both durable stores and describe keyed…
santoshkumarradha Oct 17, 2026
ec11da9
Return a service's output page as a contiguous prefix and say when a …
santoshkumarradha Oct 17, 2026
0acc6e6
Document contiguous service output pages
santoshkumarradha Oct 17, 2026
fde448b
Keep an unkeyed task note unread until its identity is known
santoshkumarradha Oct 17, 2026
2bad420
Answer process actions from the holding registry, never rerun an unse…
santoshkumarradha Oct 17, 2026
7d46dab
Carry the stamped process doors across the engine wire
santoshkumarradha Oct 17, 2026
99225b2
Never report a committed render stopped
santoshkumarradha Oct 17, 2026
9e62a6e
Identify a process's managed log for an opener without granting a path
santoshkumarradha Oct 17, 2026
2823a4f
Serve processes.actions, processes.stop_all and processes.log_target …
santoshkumarradha Oct 17, 2026
62b5285
Refuse expired process actions and unverifiable legacy stops
santoshkumarradha Oct 17, 2026
a6e5435
Read scoped memory counts in a cancellable snapshot without legacy te…
santoshkumarradha Oct 17, 2026
d14c2bb
Expose live configured memory scope counts without opening closed con…
santoshkumarradha Oct 17, 2026
8936514
Keep unheld process endings unknown when stopping one agent
santoshkumarradha Oct 17, 2026
8f8c55f
feat(factory): port factory core and GitHub contracts to app v3
santoshkumarradha Oct 17, 2026
7d92556
feat(app): attach remote factories through typed stdio methods
santoshkumarradha Oct 17, 2026
8c6a72a
Serve a program's report only on the receipt of the launch that wrote it
santoshkumarradha Oct 16, 2026
70b71df
Keep oversized issued reports known while refusing their bytes
santoshkumarradha Oct 16, 2026
6b865d9
Merge remote-tracking branch 'origin/app/v3' into work/ui2-attachment…
santoshkumarradha Oct 17, 2026
fd69086
feat(factory): port CLI workers and session tools to app v3
santoshkumarradha Oct 17, 2026
4240413
fix(factory): preserve runner model pins and manual retrieval
santoshkumarradha Oct 17, 2026
73a13db
Merge remote-tracking branch 'origin/app/v3' into HEAD
santoshkumarradha Oct 17, 2026
09f6e1f
test(factory): verify live OpenRouter stage reaches proof approval
santoshkumarradha Oct 17, 2026
c6dc81c
Merge remote-tracking branch 'origin/app/v3' into work/factory-engine…
santoshkumarradha Oct 17, 2026
3c1d57a
Merge remote-tracking branch 'origin/app/v3' into work/factory-engine…
santoshkumarradha Oct 17, 2026
8f200f6
Add guarded typed factory job actions to app v3
santoshkumarradha Oct 17, 2026
cca93c9
Merge remote-tracking branch 'origin/app/v3' into work/factory-action…
santoshkumarradha Oct 17, 2026
92f6dcc
Limit human factory invites and keep failed joins unspent
santoshkumarradha Oct 17, 2026
bbe0f8f
Merge remote-tracking branch 'origin/app/v3' into work/factory-invite…
santoshkumarradha Oct 17, 2026
96da8f2
Make factory refusal test dial a closed listener deterministically
santoshkumarradha Oct 17, 2026
7efa3f3
Guard app registry updates and keep memory counting within the source…
santoshkumarradha Oct 17, 2026
78640f3
Set up local factories and enable their runner only on explicit request
santoshkumarradha Oct 17, 2026
96b1d53
Carry verified GitHub profiles across factory surfaces and preserve s…
santoshkumarradha Oct 17, 2026
2a28790
Avoid pipeline discovery fanout during GitHub factory setup
santoshkumarradha Oct 17, 2026
3b10186
Keep factory setup owner labels truthful across repository discovery
santoshkumarradha Oct 17, 2026
472faa6
Use unique credentials in factory action test fixtures
santoshkumarradha Oct 17, 2026
81b49d0
Require current GitHub credentials when resuming saved factory setup
santoshkumarradha Oct 17, 2026
afaa91d
Restore explicitly started local factories quietly across app restarts
santoshkumarradha Oct 17, 2026
241763f
Open pipeline pull requests with the signed-in caller GitHub credential
santoshkumarradha Oct 17, 2026
a3a0f1a
Add opt-in live acceptance for pipeline pull request ownership
santoshkumarradha Oct 17, 2026
ba2ca9f
Expose caller GitHub sign-in without private factory identity data
santoshkumarradha Oct 17, 2026
69a1273
Add caller-scoped factory sign-out and session revocation
santoshkumarradha Oct 17, 2026
5f8519d
Require verified GitHub attestation and explicit sign-out capability
santoshkumarradha Oct 17, 2026
64ac8d6
Add caller-scoped factory invite management and native clipboard deli…
santoshkumarradha Oct 17, 2026
ad3eeb3
Redact invitation metadata before labels are truncated
santoshkumarradha Oct 17, 2026
dc0f457
Add operator repository switches with serialized server updates
santoshkumarradha Oct 17, 2026
4b5ffe4
Negotiate POST for factory access-link checks and polls
santoshkumarradha Oct 17, 2026
24c8d6b
Expose caller-scoped pipeline pull requests over appwire
santoshkumarradha Oct 17, 2026
124ea81
Make runner capacity changes govern live and waiting execution
santoshkumarradha Oct 17, 2026
a309e35
feat(factory): add caller-scoped pipeline source and preview
santoshkumarradha Oct 17, 2026
87359ed
feat(factory): allow owners to change live runner capacity
santoshkumarradha Oct 17, 2026
e45342f
fix(factory): keep priority marks out of execution order
santoshkumarradha Oct 17, 2026
0c2c3db
test(factory): verify real worker registration and synchronize stream…
santoshkumarradha Oct 17, 2026
4c6403c
fix(factory): keep machine details private across reads and live events
santoshkumarradha Oct 17, 2026
437eed1
feat(factory): match explicit queue filter tokens without model calls
santoshkumarradha Oct 17, 2026
337d635
test(factory): verify proxy credentials through caller-private runner…
santoshkumarradha Oct 17, 2026
b80ec20
Preserve pipeline runtime fields and hold unsafe steps (#1846)
santoshkumarradha Oct 17, 2026
7d9f662
Confirm factory runtime support before accepting pipeline source (#1847)
santoshkumarradha Oct 17, 2026
3eadf13
Honor the saved one-model policy for every factory worker launch (#1848)
santoshkumarradha Oct 17, 2026
de27c9e
Preserve complete GitHub assignee facts in factory intake (#1849)
santoshkumarradha Oct 17, 2026
27363c9
Guard runtime pipeline changes with exact factory source attestation …
santoshkumarradha Oct 17, 2026
1e46249
Restore solo factory approval without assigning an owner (#1851)
santoshkumarradha Oct 17, 2026
d0c33af
Preview guarded runtime pipeline step edits (#1852)
santoshkumarradha Oct 17, 2026
734eb4c
Keep native factory startup quiet and restore its current local conne…
santoshkumarradha Oct 17, 2026
add52e3
Clear stale factory start evidence after issue edits (#1854)
santoshkumarradha Oct 17, 2026
e5d7ad5
Open live factory stage conversations in the app (#1855)
santoshkumarradha Oct 17, 2026
0dc6ad8
Start local factory reads and repository rules after explicit Run (#1…
santoshkumarradha Oct 17, 2026
a55c0a5
Resume approved factory plans at the gate and require fresh consent (…
santoshkumarradha Oct 17, 2026
f449f89
Show explicit factory priority marks without inferring from issue typ…
santoshkumarradha Oct 17, 2026
8f2b20a
Keep cold factory send-back feedback and resume the preceding step (#…
santoshkumarradha Oct 17, 2026
126ab9c
Make factory rule previews match intake decisions and explicit size l…
santoshkumarradha Oct 17, 2026
f616d71
Clarify runtime preview claims when clearing the last field (#1861)
santoshkumarradha Oct 17, 2026
2975ea5
fix(factory): withhold stage chat paths from job readers (#1863)
santoshkumarradha Oct 17, 2026
c5d4342
fix(factory): keep stage crew ownership and instructions truthful (#1…
santoshkumarradha Oct 17, 2026
d490c80
fix(factory): honor session memory and held-folder contracts (#1866)
santoshkumarradha Oct 17, 2026
0324d17
fix(factory): discover Homebrew gh from native app launches (#1867)
santoshkumarradha Oct 17, 2026
8c67f35
fix(factory): show sizes only from recorded evidence (#1864)
santoshkumarradha Oct 17, 2026
d1dd9ba
feat(factory): expose sourced read size separately from labels (#1865)
santoshkumarradha Oct 17, 2026
8a6efcd
Record the exact crew an automation was made in, unknown unless an ac…
santoshkumarradha Oct 17, 2026
710f8a7
Keep a crew stamp through retry, queue edits and older hosts, and sta…
santoshkumarradha Oct 17, 2026
6410d7f
Serve a crew's orders by the team they were recorded as made in, with…
santoshkumarradha Oct 17, 2026
edc4697
Prove the older-host mark refusal, drop a test race, and say plainly …
santoshkumarradha Oct 17, 2026
43c3881
Make creation context presence-based, check it at acceptance, keep it…
santoshkumarradha Oct 17, 2026
1d95f54
Downgrade an unprovable creation context to unknown instead of refusi…
santoshkumarradha Oct 17, 2026
1187e23
Make a turn unknown when a message with another creation context is s…
santoshkumarradha Oct 17, 2026
c68259b
Bind a crew's orders walk to a store revision, bound its bytes before…
santoshkumarradha Oct 17, 2026
a9143ec
Read a crew's orders within bounds on every selected field: project o…
santoshkumarradha Oct 17, 2026
3902736
Find the fixture's marker in any message of the request, stream its t…
santoshkumarradha Oct 17, 2026
b19fe89
Type a task note's outcome from its producer, and carry its key throu…
santoshkumarradha Oct 17, 2026
a5b78a2
Carry a task note's typed outcome across App.TaskAction without chang…
santoshkumarradha Oct 17, 2026
377ed1e
Answer a task note with the engine's typed outcome and never send it …
santoshkumarradha Oct 17, 2026
e263950
Type a failed commit and a post-dispatch panic as unknown, and prove …
santoshkumarradha Oct 17, 2026
6c6f3f2
Refuse a note's commit with SQLite's own commit hook, and ship no tes…
santoshkumarradha Oct 17, 2026
5b65409
Type a failed plan-store commit as unknown on every receipt road, a b…
santoshkumarradha Oct 17, 2026
db2ec39
Answer tasks.brief from its typed receipt, because the socket erases …
santoshkumarradha Oct 17, 2026
d51cdfb
Keep untyped note action failures unknown regardless of current welcome
santoshkumarradha Oct 17, 2026
c7da2c6
Document typed refusal authority without welcome-based certainty
santoshkumarradha Oct 17, 2026
44edfce
Add durable share_deliverable operation receipt and admission.
santoshkumarradha Oct 17, 2026
35e87b3
Bound and validate durable publication receipts before replay
santoshkumarradha Oct 17, 2026
917d3dc
Inspect explicitly shared files with bounded reads and exact ownership
santoshkumarradha Oct 17, 2026
8d333bd
Hold publication's own roads to the fifteen-decision ceiling
santoshkumarradha Oct 17, 2026
1bd855a
Persist the full immutable share plan before any append
santoshkumarradha Oct 17, 2026
53090b5
Freeze the share plan in claim-private durable bytes and bind rows to…
santoshkumarradha Oct 17, 2026
47a83d4
Publish shared files from the frozen plan under a typed shared origin
santoshkumarradha Oct 17, 2026
1c9d927
Prove the share publisher end to end and keep timeouts retryable
santoshkumarradha Oct 17, 2026
6afe703
Share a task branch's file through an owned snapshot that stays avail…
santoshkumarradha Oct 17, 2026
d2a9978
Carry shared files on the app wire as shared, never Made
santoshkumarradha Oct 17, 2026
1efad98
Prove a share never touches a genuine created row of the same file
santoshkumarradha Oct 17, 2026
2de2814
Close the M3 review's N2, N5, N10, N4 and N7 before the wire freeze
santoshkumarradha Oct 17, 2026
483cb59
Keep the legacy unkeyed note regression on the typed receipt matcher
santoshkumarradha Oct 17, 2026
a08c6cc
Merge current Factory app-v3 work with reviewed sharing and crew rece…
santoshkumarradha Oct 17, 2026
0d47638
app: carry guarded per-job step editing (#1869)
santoshkumarradha Oct 17, 2026
ea2febb
Merge remote-tracking branch 'origin/app/v3' into work/engine-reviewe…
santoshkumarradha Oct 17, 2026
e3dc7db
Carry a handed-over task row's program, ending and branch to the cold…
santoshkumarradha Oct 17, 2026
59659ff
Say that a stopped flag does not name who stopped the task
santoshkumarradha Oct 17, 2026
9a766d6
Exercise stopped job facts through their real kept-row producer
santoshkumarradha Oct 17, 2026
0e0c506
Read task notes through bounded opaque-id pages without hiding later …
santoshkumarradha Oct 17, 2026
beb8b58
Answer a held plan lock at once instead of waiting behind a writer
santoshkumarradha Oct 17, 2026
f5e0317
Refuse an overlong task id before it is copied into SQLite
santoshkumarradha Oct 17, 2026
9c59f6d
Align the note cursor error methods with gofmt
santoshkumarradha Oct 17, 2026
9ed62d1
Hand workers the fifty-first and two-hundred-first note from a paged …
santoshkumarradha Oct 17, 2026
d4ea1a7
Refuse a note the readers would refuse, and stop promising a way to c…
santoshkumarradha Oct 17, 2026
efa9c38
Check the same handle before the reopen in the note writer bound test
santoshkumarradha Oct 17, 2026
acd43f6
Say the note writer's parity is per note, and that a long plan name s…
santoshkumarradha Oct 17, 2026
413ad69
Scope the note author boundary test comment to its field
santoshkumarradha Oct 17, 2026
af1012d
Read a note's envelope for the inbox, so a long plan name holds nothing
santoshkumarradha Oct 17, 2026
a6072eb
Correct the envelope tests: seed the tasks, derive the walk bound, re…
santoshkumarradha Oct 17, 2026
440cf20
fix(factory): keep step edits before proof and landing (#1871)
santoshkumarradha Oct 17, 2026
c8085b3
fix(factory): keep manager session paths on workers (#1873)
santoshkumarradha Oct 18, 2026
00773ef
fix(factory): preserve step bounds and truthful thinking edits (#1872)
santoshkumarradha Oct 18, 2026
f5faa03
feat(factory): send waiting plans back for revision (#1874)
santoshkumarradha Oct 18, 2026
cba02da
Factory pipeline structural edit previews (#1875)
santoshkumarradha Oct 18, 2026
83447f2
Use current finished plan declarations for factory file counts (#1876)
santoshkumarradha Oct 18, 2026
c7cbcb7
fix: a reading the chat hands off can only look, and quick endings sa…
AbirAbbas Oct 19, 2026
70e33e1
fix(app): carry a reply on after the desktop engine is killed, and st…
AbirAbbas Oct 19, 2026
7268a26
Windows: run commands in Git Bash, and open SQLite stores on Windows …
AbirAbbas Oct 19, 2026
532cded
feat(appwire): skills.list and skills.set for the slash /skill command
santoshkumarradha Oct 20, 2026
7dff77b
fix(session): clean background exits land in context without waking t…
santoshkumarradha Oct 20, 2026
bee54e7
feat(appwire): slash wire methods (conv)
santoshkumarradha Oct 20, 2026
61908ad
feat(appwire): slash wire methods (misc)
santoshkumarradha Oct 20, 2026
b92c28d
feat(appwire): slash wire methods (effort)
santoshkumarradha Oct 20, 2026
e0c0c47
test(tui3): name the far skill-folder scan beside the line
santoshkumarradha Oct 20, 2026
51bcc9e
Merge slash engine lane: conv
santoshkumarradha Oct 20, 2026
504f59c
Merge slash engine lane: skills
santoshkumarradha Oct 20, 2026
eff69fb
Merge slash engine lane: misc
santoshkumarradha Oct 20, 2026
cb4ee1d
Merge slash engine lane: effort
santoshkumarradha Oct 20, 2026
1520cf8
Merge app/v3 (I29) into feat/slash-eng
santoshkumarradha Oct 20, 2026
631586c
test(e2e): the no-shelf sentence now lives in internal/skillpick
santoshkumarradha Oct 20, 2026
95b842a
style: gofmt tuiwords table
santoshkumarradha Oct 20, 2026
912de1f
feat(appwire): agents.run_harness runs a saved harness with the messa…
santoshkumarradha Oct 20, 2026
0e943b0
test(tui3): a start handed to submitting runs off the loop
santoshkumarradha Oct 20, 2026
c67da7a
fix(appwire): delete needs confirm and stops kept services; bounded h…
santoshkumarradha Oct 20, 2026
30ade03
Merge slash engine lane: harness
santoshkumarradha Oct 20, 2026
088ea65
Merge slash engine lane: fix
santoshkumarradha Oct 20, 2026
7490aea
fix(app): tool ends and history name the process their command became…
AbirAbbas Oct 20, 2026
ddeff9a
Merge remote-tracking branch 'origin/app/v3' into feat/slash-eng
santoshkumarradha Oct 20, 2026
4e6b499
perf(app): wave 1: idle engine sleeps, agents open lazily, files are …
santoshkumarradha Oct 20, 2026
58ab1e0
feat(app): crews.organize suggests crews from folders and one naming …
santoshkumarradha Oct 20, 2026
85c1161
fix(session): doorstep drains read the conversation folder under the …
santoshkumarradha Oct 20, 2026
f2541b1
feat(app): permission asks carry scopes; Always saves the chosen scop…
santoshkumarradha Oct 21, 2026
98c1f34
app: the map graph carries the brief's and each task's exact origin, …
santoshkumarradha Oct 21, 2026
f0b9fbb
session: origins live on the record, resolved on demand; entries stay…
santoshkumarradha Oct 21, 2026
2ac7e48
fix(app): replayed background jobs carry their command, times, exit c…
santoshkumarradha Oct 21, 2026
a716917
Factory: automate issue-to-PR work and maintain PRs through review (#…
ZeroPoint95 Oct 23, 2026
b5e7ef3
Merge origin/dev into app/v3
santoshkumarradha Oct 24, 2026
697120b
Merge remote-tracking branch 'origin/app/v3' into merge/dev-into-app-v3
santoshkumarradha Oct 24, 2026
2e83565
Merge origin/dev into app/v3 (second pass)
santoshkumarradha Oct 24, 2026
ca3f3a3
plandb and SQLite stores: open a database at its literal name
santoshkumarradha Oct 24, 2026
1e9b731
provider: restore observer refusal on tool loops, redirect policy for…
santoshkumarradha Oct 24, 2026
6be7d43
Merge fixes: refusal marking, credential guard in the locked writer, …
santoshkumarradha Oct 24, 2026
6aed356
session merge fixes: receipt marks, entry clone and cost, ledger fixt…
santoshkumarradha Oct 24, 2026
61cefbe
plandb commit gate follows the literal store URI; DisplayEntry guard …
santoshkumarradha Oct 24, 2026
014ff60
Merge origin/dev into app/v3 (#1919-#1926)
santoshkumarradha Oct 24, 2026
9e2ce4c
fix: running sessions follow the permission mode from Settings (#1930)
santoshkumarradha Oct 25, 2026
a71555e
fix: conversation writes and edits record deliverables with stable id…
santoshkumarradha Oct 25, 2026
2f91a03
perf: engine reads plans and task indexes once per change (#1936)
santoshkumarradha Oct 25, 2026
0063de4
Idle app engine CPU down about tenfold; cmd/codeaf suite runs to the …
ZeroPoint95 Oct 25, 2026
85b6049
Merge origin/dev into app/v3 (#1935-#1940) (#1942)
santoshkumarradha Oct 25, 2026
bd54c8c
app engine: read crew members without holding them, and size the heap…
santoshkumarradha Oct 25, 2026
8307937
docs: desktop engine memory method and results; change entry
santoshkumarradha Oct 25, 2026
d94f35e
app engine: say why the rest stamp is taken after the release
santoshkumarradha Oct 25, 2026
79cf4ed
fix(engine): coordinate idle release and validate bounded memory caches
santoshkumarradha Oct 25, 2026
14d6a1a
fix(engine): close reader and cache admission gaps
santoshkumarradha Oct 25, 2026
a3563fc
fix(engine): preserve unchanged persistence and validate task deletions
santoshkumarradha Oct 25, 2026
926b37f
perf: cut the app engine's resident memory, ported onto dev
AbirAbbas Nov 13, 2026
1f217f8
Port #1933 onto dev
AbirAbbas Nov 13, 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
46 changes: 46 additions & 0 deletions PERF.md
Original file line number Diff line number Diff line change
Expand Up @@ -785,3 +785,49 @@ The macOS 60 s steady profile fell from 3.03% to 2.10% of a core. What remains
is the factory's lease reads on runner requests (17%) and the chat presence
beat (13%). The rig does not follow a live AgentField run, which the live
round's idle did; the AgentField write above is that path's share.

## Resident memory of the desktop engine

`codeaf app` holds a conversation in memory only while something needs it. The
method and measurements are in [docs/perf/memory-2026-10-24.md](docs/perf/memory-2026-10-24.md).

- **Members at rest are read, not held.** `tasks.list`, `asks.list` and
`processes.list` on a member of an open crew answer from its files when its
presence shows no working turn, question, task or process, no service is kept
and no stage is lent. `tasks.list` builds the owner-backed list by holding the
conversation for the length of one read (at most `appRestReads` = 2 at once),
then keeps it under a stamp of the files it was built from: in memory up to
`appRestMemoBytes` = 24 MiB (least recently read first; a list larger than
that is not kept), and as `<home>/cache/app-tasks/<agent>.json` for the
next launch, valid for the same build and the same stamp only. Disk storage
keeps at most `appRestDiskTotalBytes` = 96 MiB and `appRestDiskEntries` = 256
files, evicting oldest writes first. The inventory is scanned on first use and
every `appRestDiskScanEvery` = 1 minute by the idle sweep, which also prunes
missing or deleted agents; writes update the inventory without directory scans.
Agent deletion removes both entries immediately. Byte-identical settled task
checkpoints preserve their identity on open, so snapshot validation can admit
conversations with saved tasks. Owner-overlay failures propagate and are
never cached; reader completion is deferred and one-shot. Record, rest and
project-index admission share the two-second mtime/ctime settling guard.
`TestAppReadingAnIdleCrewMemberDoesNotKeepItsConversation` and
`TestAppReadsARestingMembersTasksFromTheCacheAfterARelaunch` pin the opens.
- **A crew member with nothing in flight is let go after `appAgentIdle`** like any
other conversation; the crew opens it again for traffic.
- **Journal records** (`RecordCache`) keep at most `recordCacheEntries` = 8
records and drop one not read for `recordCacheIdle` = 30 s. The 256 MiB byte
budget and the 16 MiB per-file limit are unchanged.
- **The project task index** keeps the decoded rows of the last
`taskIndexKeptPaths` = 4 indexes of at most `taskIndexKeptBytes` = 4 MiB each.
- **Plan reads** (`plandb.Store`) reload the plan only when SQLite's
`data_version` or the database/log stamp moved.
`TestRepeatedReadsOfAnUnchangedPlanLoadItOnce` allows 3 MiB for 200 reads.
`TestAppTasksOpensThePlanOnceForAllTheRunRows` allows 16 MiB to list 150 rows.
- **The collector percent follows the live heap** (`memtrim.go`): the app starts
at Go's default percent 100. The governor selects 400 for a small heap, and a
larger one is given the percent that
lets about `heapHeadroom` = 32 MiB of garbage build up, never below
`heapGCMin` = 10. An explicit `GOGC` decides instead. When more than 48 MiB
and half of the live heap is held and unused, `debug.FreeOSMemory` runs, at most
once a minute. macOS keeps freed pages in a process's resident size until it
needs them (`MADV_FREE_REUSABLE`), so `ps` RSS shows the peak of a burst while
the footprint (`vmmap --summary`, Activity Monitor) shows what is held.
91 changes: 78 additions & 13 deletions cmd/codeaf/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func runApp(args []string) error {
defer leaving()
defer leave.On(leaving, nil)()
guard.Go("app/parent", func() { watchAppParent(ctx, os.Getppid, appParentPoll, leaving) })
startHeapTrimmer(ctx)
// THE APP'S KEYS LIVE IN THIS PROCESS'S MEMORY, installed before anything
// can read a key, and no profile write may put one on disk while they are.
defer config.UseAppCredentials(config.NewAppCredentials())()
Expand Down Expand Up @@ -606,6 +607,14 @@ type appBackend struct {
devices *appDevices
stopSyncedSettings func()

// restMemo is the task lists of members at rest, so reading them does not
// hold their conversations (apprestmemo.go).
restMemo appRestMemo
restSlots chan struct{}
// waitReaders joins an explicit close's readers; nil waits on their signal.
// Tests replace the wait to observe the unlocked admission gate.
waitReaders func(<-chan struct{})

// organizeProposer supplies a naming door when the backend is embedded without held conversations.
organizeProposer session.TeamProposer

Expand Down Expand Up @@ -842,8 +851,13 @@ type appAgent struct {
// listening is when this light record began watching crew traffic.
listening time.Time

// gate serializes opening and letting go of this one agent, so two sends
// racing for a closed conversation open it once.
// readers keeps the held conversation alive until the last disk/owner read
// returns. These fields are guarded by b.mu; pinning also holds gate.
readers int
readersDone chan struct{}
restRead bool
releasing bool
// gate serializes opening, work admission and release for this agent.
gate sync.Mutex
nameGate sync.Mutex // serializes a rename RPC and its view update
view appwire.Agent
Expand Down Expand Up @@ -1110,6 +1124,7 @@ func newAppBackend(emit appwire.Emitter, open appOpener) *appBackend {
return func() { t.Stop() }
},
agents: map[string]*appAgent{},
restSlots: make(chan struct{}, appRestReads),
closedDone: make(chan struct{}),
sweepStop: make(chan struct{}),
sweepDone: make(chan struct{}),
Expand Down Expand Up @@ -3388,10 +3403,11 @@ func (b *appBackend) workEvent(id string, live *appLive, event session.Event) {
// started, or is interrupted the moment it is ([appBackend.bootSettle]). No
// stop waits on the gate an open holds.
func (b *appBackend) Stop(id string) error {
a, err := b.findCrewOwner(id)
a, endRead, err := b.findCrewOwner(id)
if err != nil {
return err
}
defer endRead()
kept := false
b.locked(func() {
if a.starting {
Expand Down Expand Up @@ -3434,6 +3450,7 @@ func (b *appBackend) CloseAgent(id string) error {
func (b *appBackend) closeAgent(a *appAgent) (view appwire.Agent) {
a.gate.Lock()
defer a.gate.Unlock()
b.lockRelease(a)
return b.closeAgentLocked(a)
}

Expand All @@ -3454,7 +3471,7 @@ func (b *appBackend) release(a *appAgent) {
var id string
b.locked(func() {
id = a.view.ID
live, a.live, a.viewOpen = a.live, nil, false
live, a.live, a.viewOpen, a.restRead, a.releasing = a.live, nil, false, false, false
if live != nil {
a.lastLive = b.now()
// Its conversation's open questions go with it, unanswered and
Expand All @@ -3469,6 +3486,26 @@ func (b *appBackend) release(a *appAgent) {
b.forgetAsksOf(id, live)
}

func (b *appBackend) releaseIdle(a *appAgent) bool {
var live *appLive
var id string
b.locked(func() {
if a.readers > 0 || a.viewOpen || a.live == nil || a.live.running || a.live.compacting {
return
}
id = a.view.ID
live, a.live, a.viewOpen, a.restRead, a.crewHeld, a.releasing = a.live, nil, false, false, false, false
a.lastLive = b.now()
b.dropAsksLocked(a.view.ID, live.asks)
})
if live == nil {
return false
}
b.finish(live)
b.forgetAsksOf(id, live)
return true
}

// finish gives a conversation that is no longer held back, and shuts its
// outbox once the turn and the lanes have said their last.
func (b *appBackend) finish(live *appLive) {
Expand Down Expand Up @@ -3515,10 +3552,13 @@ func (b *appBackend) finish(live *appLive) {
// ListAsks answers the agent's open asks. An agent with no conversation held
// has none this process can answer.
func (b *appBackend) ListAsks(id string) ([]appwire.Ask, error) {
a, err := b.findCrewOwner(id)
// A member at rest has no question a held conversation would add: one
// waiting on the person says so in its presence and is not at rest.
a, endRead, err := b.findCrewReader(id)
if err != nil {
return nil, err
}
defer endRead()
var asks []appwire.Ask
b.locked(func() {
if a.live != nil {
Expand Down Expand Up @@ -3560,10 +3600,11 @@ func (b *appBackend) answerAskThrough(id, askID, option, text, scope string, sec
if handled, err := b.answerCrewAsk(id, askID, option, text, ""); handled {
return err
}
a, err := b.findCrewOwner(id)
a, endRead, err := b.findCrewOwner(id)
if err != nil {
return err
}
defer endRead()
if handled, err := b.answerMoney(a, askID, option, text); handled {
return err
}
Expand Down Expand Up @@ -4532,10 +4573,25 @@ func (b *appBackend) watchSpendRows() (stop func()) {
// checkpoint does not name — and lays over them what a held conversation has
// said since.
func (b *appBackend) ListTasks(id string) ([]appwire.Task, error) {
a, err := b.findCrewOwner(id)
if a, err := b.find(id); err == nil && b.crewKeeps(id) && !b.isClosing() && !b.tidied(id) && b.memberRests(a) {
return b.restingTasks(a, id)
}
return b.listTasksOf(id)
}

// listTasksOf is ListTasks for a conversation the crew keeps held when it is
// busy, and the files' answer otherwise.
func (b *appBackend) listTasksOf(id string) ([]appwire.Task, error) {
a, endRead, err := b.findCrewOwner(id)
if err != nil {
return nil, err
}
defer endRead()
return b.listTasksHeld(a, id)
}

// listTasksHeld reads disk and overlays the owner while the caller pins a.
func (b *appBackend) listTasksHeld(a *appAgent, id string) ([]appwire.Task, error) {
var transcript string
var fallback time.Time
// A quick task is listed by AppQuickTasks, never as a task here (#1880).
Expand Down Expand Up @@ -4627,7 +4683,11 @@ func (b *appBackend) ListTasks(id string) ([]appwire.Task, error) {
add(appwire.Task{Result: result, ID: appIndexTaskID(id, row.ID), Agent: id, Parent: parent, Title: title, State: state, UpdatedAt: at, YourCall: state == appwire.TaskUnverified})
}
}
for taskID, task := range b.heldTaskViews(a) {
owner, err := b.heldTaskViews(a)
if err != nil {
return nil, err
}
for taskID, task := range owner {
if quickIDs[taskID] {
continue
}
Expand Down Expand Up @@ -4854,6 +4914,7 @@ func (b *appBackend) Close() error {
func (b *appBackend) letGo(a *appAgent) {
a.gate.Lock()
defer a.gate.Unlock()
b.lockRelease(a)
b.release(a)
}

Expand All @@ -4863,6 +4924,7 @@ func (b *appBackend) letGoTimed(a *appAgent, w io.Writer) {
began := time.Now()
a.gate.Lock()
defer a.gate.Unlock()
b.lockRelease(a)
gated := time.Now()
var id string
b.locked(func() { id = a.view.ID })
Expand Down Expand Up @@ -4921,10 +4983,11 @@ func (b *appBackend) sweepOnce() {
_, _ = b.SyncStatus()
}
now := b.now()
appRestDisk.maintain(now)
var idle []*appAgent
b.locked(func() {
for _, a := range b.agents {
if live := a.live; live != nil && !a.viewOpen && !live.running && now.Sub(live.lastUse) >= appAgentIdle {
if live := a.live; live != nil && !a.viewOpen && !live.running && a.readers == 0 && now.Sub(live.lastUse) >= appAgentIdle {
idle = append(idle, a)
}
}
Expand All @@ -4945,13 +5008,15 @@ func (b *appBackend) sweepAgent(a *appAgent, now time.Time) {
keep := true
b.locked(func() {
live = a.live
keep = live == nil || a.viewOpen || live.running || now.Sub(live.lastUse) < appAgentIdle
keep = live == nil || a.viewOpen || live.running || a.readers > 0 || now.Sub(live.lastUse) < appAgentIdle
})
// A member of an open crew stays held while the crew is open.
if !keep && !b.liveNeedsYou(live) && !b.crewKeeps(a.view.ID) && !b.serviceKeeps(a.view.ID) {
// A member of an open crew stays held while it has work in flight or a
// reason the crew would open it again at once; one with nothing to do goes
// like any other, and the crew opens it when traffic comes (applazy.go).
if !keep && appLiveWorkSettled(live) && !b.liveNeedsYou(live) && !b.serviceKeeps(a.view.ID) && (!b.crewKeeps(a.view.ID) || b.memberQuiet(a)) {
// The state the app reads does not move: the conversation is as
// idle on disk as it was in memory.
b.release(a)
b.releaseIdle(a)
}
}

Expand Down
6 changes: 4 additions & 2 deletions cmd/codeaf/appattention.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ func (b *appBackend) ShowAsk(agent, id string) (*appwire.Ask, error) {
}

func (b *appBackend) clockAsk(agent, id string, start bool) (*appwire.Ask, error) {
a, err := b.findCrewOwner(agent)
a, endRead, err := b.findCrewOwner(agent)
if err != nil {
return nil, err
}
defer endRead()
live := b.liveOf(a)
if live == nil {
return nil, appwire.Errorf(appwire.CodeNotFound, "the ask %s is not open", id)
Expand Down Expand Up @@ -160,10 +161,11 @@ func (b *appBackend) TaskSince(id, after string) (appwire.Since, error) {
if !strings.HasPrefix(after, prefix) {
return appwire.Since{}, nil
}
a, live, err := b.heldLive(agent)
a, live, endLive, err := b.borrowLive(agent)
if err != nil {
return appwire.Since{}, err
}
defer endLive()
journal, ok := live.conn.Conv.(appTaskJournal)
if !ok {
return appwire.Since{}, nil
Expand Down
6 changes: 4 additions & 2 deletions cmd/codeaf/appbudget.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,11 @@ func (b *appBackend) stampAgentBudget(a *appAgent) appwire.Agent {

// AgentBudget answers agents.budget.get.
func (b *appBackend) AgentBudget(id string) (appwire.AgentBudget, error) {
a, err := b.findCrewOwner(id)
a, endRead, err := b.findCrewOwner(id)
if err != nil {
return appwire.AgentBudget{}, err
}
defer endRead()
return b.budgetOf(id, b.liveOf(a))
}

Expand All @@ -132,10 +133,11 @@ func (b *appBackend) SetAgentBudget(set appwire.AgentBudgetSet) (appwire.AgentBu
if set.USD != nil && (*set.USD <= 0 || math.IsNaN(*set.USD) || math.IsInf(*set.USD, 0)) {
return appwire.AgentBudget{}, appwire.Errorf(appwire.CodeBadParams, "usd must be a positive amount, or null for none")
}
a, err := b.findCrewOwner(set.ID)
a, endRead, err := b.findCrewOwner(set.ID)
if err != nil {
return appwire.AgentBudget{}, err
}
defer endRead()
if b.isClosing() {
return appwire.AgentBudget{}, appwire.Errorf(appwire.CodeClosed, "codeaf is shutting down")
}
Expand Down
18 changes: 10 additions & 8 deletions cmd/codeaf/appclose.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ func appTaskWasInterrupted(p session.SessionPresence, fresh bool, id string, sta

// heldTaskViews reads after the disk so a start arriving during the listing
// wins. Locally owned tasks come from the engine, even ahead of its event lane.
func (b *appBackend) heldTaskViews(a *appAgent) map[string]appwire.Task {
func (b *appBackend) heldTaskViews(a *appAgent) (map[string]appwire.Task, error) {
heard := map[string]appwire.Task{}
var live *appLive
var id string
Expand All @@ -859,15 +859,17 @@ func (b *appBackend) heldTaskViews(a *appAgent) map[string]appwire.Task {
// A lent stage lives in this process too, and may have parked a card before the
// hold began, when no event could carry it here.
if live != nil && (live.conn.Assembled || live.conn.Lent) {
if tasks, err := live.conn.Conv.AppTasks(); err == nil {
for _, view := range tasks {
task := appTaskOfView(id, view)
task.UpdatedAt = heard[task.ID].UpdatedAt
heard[task.ID] = task
}
tasks, err := live.conn.Conv.AppTasks()
if err != nil {
return nil, err
}
for _, view := range tasks {
task := appTaskOfView(id, view)
task.UpdatedAt = heard[task.ID].UpdatedAt
heard[task.ID] = task
}
}
return heard
return heard, nil
}

// Deleted journals keep their directory for deliverables. Only their lifetime
Expand Down
5 changes: 4 additions & 1 deletion cmd/codeaf/appcompaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,11 @@ func appReadPasses(stop <-chan struct{}, passes <-chan session.Event, take func(
// compaction.ended; the pass's own events reach the page through the
// connection's pass lane ([appBackend.watchPasses]), ahead of that answer.
func (b *appBackend) CompactAgent(id string) error {
a, live, err := b.heldLive(id)
a, live, endLive, err := b.borrowLive(id)
if err != nil {
return err
}
defer endLive()
conv, ok := live.conn.Conv.(appCompactConv)
if !ok {
return appwire.Errorf(appwire.CodeUnknownMethod, "this conversation cannot be compacted from here")
Expand All @@ -240,7 +241,9 @@ func (b *appBackend) CompactAgent(id string) error {
b.locked(func() { live.compacting = false })
return appwire.Errorf(appwire.CodeBusy, "too many compactions are running; ask again in a moment")
}
endWorker := b.pinReaderGated(a)
guard.Go("app/compact", func() {
defer endWorker()
defer func() {
<-appCompactSlots
b.locked(func() { live.compacting = false })
Expand Down
Loading
Loading