fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(headless): register ArchiveRead when Harbor archives tool results - #2028

Merged
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration
Aug 3, 2026
Merged

fix(headless): register ArchiveRead when Harbor archives tool results#2028
Astro-Han merged 2 commits into
mainfrom
fix/headless-archive-read-registration

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

Harbor's headless AI SDK path archives large tool results but never bound ArchiveRead, so pruned results were replaced by placeholders instructing the model to "Call ArchiveRead with the provided ref" — a tool that did not exist on the surface. The original result left context and the named recovery path was unreachable.

This is the default Harbor path, not an opt-in: the output dir falls back to /logs/agent, the archive dir falls back to a subdirectory of it, and both stale and active prune default to enabled.

Bind ArchiveRead behind exactly the same gate as the writer:

  • Export buildArchiveReadTool from @maka/runtime. It was absent from index.ts and from the package's subpath exports, so headless could not construct the tool at all — desktop only worked because it goes through buildBuiltinTools internally.
  • Add a ref-addressed ToolResultArchiveResourceReader over the Harbor archive dir. ArchiveRead addresses an archive by maka://archive/... ref (artifact id, hash, size), which the existing replay reader cannot serve because it requires runtime-event identity. Both now share one read-and-verify helper instead of duplicating the read path, and replay keeps its stricter event-identity check layered on top rather than having it relaxed.
  • Thread the reader from runHarborCellFromEnv, which already owns the resolved env that wires the writer, so the two cannot diverge.

The structural cause — the archive capability being three independent optional fields spread across two configuration surfaces, which makes "writer on, reader tool absent" representable — is tracked separately in #2026 and deliberately not addressed here, so this fix stays behavior-only and benchmark deltas remain attributable.

Closes#2025

Verification

  • npm run test:dist --workspace @maka/headless — 1316 passed, 0 failed, 1 pre-existing skip.
  • npm run typecheck (all workspaces) — clean.
  • npm run lint, npm run format:check — clean.
  • npm run test:dist --workspace @maka/runtime — 2814 passed, 4 failed. The 4 failures (Read/Write/Edit/Glob and Grep workspace-containment tests) are pre-existing macOS /var/private/var symlink failures; verified identical on the unmodified branch point (2814 passed / 4 failed) before and after the change.

Two tests were added at the existing backend-input seam:

  • Harbor ai-sdk backend binds ArchiveRead whenever it archives tool results — fails on the unfixed code with the writer present and the tool absent, which is the reported defect.
  • Harbor ArchiveRead reads back a tool result the cell archived — an end-to-end round trip through the tool's impl. Confirmed it actually catches reader regressions by temporarily stubbing the resource reader to return not_found and watching it fail.

The pre-existing archive test only asserted that the writer exists and never that ArchiveRead was callable, so the fixture shared the same one-directional blind spot as the implementation. The test helper that projects the product surface now derives the reader from the same env as production.

Harbor's AI SDK path always resolves an archive dir (the output dir falls
back to /logs/agent, and the archive dir falls back to a subdirectory of
it), so the tool-result archive writer is on by default. Both stale and
active prune then replace large results with placeholders that explicitly
tell the model to call ArchiveRead — a tool headless never bound, because
it hand-writes its tool array and never goes through buildBuiltinTools.
The result was removed from context and the recovery path named in its
place did not exist.
Bind ArchiveRead behind exactly the same gate as the writer:
- export buildArchiveReadTool from @maka/runtime; it was unreachable
outside the package, so headless could not construct the tool at all
- add a ref-addressed ToolResultArchiveResourceReader for the Harbor
archive dir, sharing one read-and-verify helper with the replay reader
rather than duplicating it; replay keeps its stricter runtime-event
identity check layered on top
- thread the reader from runHarborCellFromEnv, which already owns the
resolved env that wires the writer, so the two cannot diverge
The test helper that projects the product surface now derives the reader
from the same env as production, so the fixture cannot drift from it.
Fixes#2025
Review cross-check found the tool surface and the archive writer disagreeing
when MAKA_CONTEXT_BUDGET=off: the writer was gone but ArchiveRead was still
bound, offering the model a tool no ref could ever satisfy. Fold the budget
gate into harborCellToolResultArchiveDir so writer and both readers derive
from one authority.
The two tests added with the fix rebuilt production wiring inside a test
helper, so deleting the real wiring left them green. Drive them through
runHarborCellFromEnv instead and observe the surface it assembles, then cover
the resource reader's failure reasons, which had none.
Drop the unreachable maxBytes/too_large branch: both call paths address an
archive by its exact recorded size, and Harbor reads the whole record.
Sign up for freeto 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.

fix(headless): register ArchiveRead when Harbor enables tool-result archiving

1 participant

@Astro-Han