Spec 146 phase 10: full protocol on a second driver #235

Description

@pseudoseed

Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
it is unblocked.

Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
created against a real server
while every in-memory test passed.

The plan section is reproduced verbatim so it is not fetched by path.


Phase 10: Full protocol on a second driver

Dependencies: Phase 9

Objective

Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
24-hour gate clock that Phase 14 depends on.

Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

Files to Create / Modify

  • packages/porch-driver/__tests__/full-protocol.test.ts
  • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
  • codev/research/146-driver-parity.md
  • codev/research/146-long-gate-evidence.md

Deliverables

  • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
    that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
    assumed.
  • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
    event.
  • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
    146-driver-parity.md rather than worked around silently.
  • The 24-hour gate test is started in this phase and its evidence recorded when it
    completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
    here is the only way the schedule works.
  • Tests for this phase.

Acceptance Criteria

  • Criterion 1 passes on two drivers.
  • Criterion 2 passes: restart mid-protocol, no lost completion.
  • A one-hour gate resumes with context on both drivers.
  • The 24-hour gate run is started and its start recorded.
  • Build and tests pass.

Test Plan

Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
real; a fake clock does not test what the reaper does.



What phase 9 actually left you — read the PR before starting

#221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
this seam. The ones that shape your work:

  • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
    in either direction.
    A keyed read that missed and then took the unkeyed one restores a
    cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
    one process; a turn dispatched to the wrong server succeeds.
  • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
    await there stalls delivery for every agent in every workspace including PTY-only ones. The
    synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
    ensureThreadBackendReady is CLI-only.
  • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
    its own command id.
    Two earlier attempts were wrong in ways worth not repeating: matching on
    message text let duplicate text recover a stale intent, and draining the whole journal replayed
    siblings' intents so they duplicated one agent over.
  • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
    no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
    receives no gate notice.
  • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
    shape in deliverToThread is the template; do not let each command grow its own copy.

Live harness

tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
a provider.

Standing rules for this program

"I could not tell" must never be spelled the same way as "no." Reference implementations now in
the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

A green suite is evidence only about what it ran. Name which suites exist and which files each
covers before quoting one. Five exist.

Assert the mutation applied before trusting what it proves. A mutation check that silently
no-ops produces a passing test, which looks exactly like the guard working.

Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
code did not provide, and two independent reviewers went straight to them. The corrected form now in
the tree: argv heuristic, not proof of parentage.

Not in scope

#179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
the program). Do not attempt either.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/porchProtocol orchestrator

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e 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

      Spec 146 phase 10: full protocol on a second driver #235

      Description

      @pseudoseed

      Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
      it is unblocked.

      Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
      production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
      e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
      t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
      created against a real server
      while every in-memory test passed.

      The plan section is reproduced verbatim so it is not fetched by path.


      Phase 10: Full protocol on a second driver

      Dependencies: Phase 9

      Objective

      Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
      24-hour gate clock that Phase 14 depends on.

      Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
      deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

      Files to Create / Modify

      • packages/porch-driver/__tests__/full-protocol.test.ts
      • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
      • codev/research/146-driver-parity.md
      • codev/research/146-long-gate-evidence.md

      Deliverables

      • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
        that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
        assumed.
      • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
        event.
      • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
        146-driver-parity.md rather than worked around silently.
      • The 24-hour gate test is started in this phase and its evidence recorded when it
        completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
        here is the only way the schedule works.
      • Tests for this phase.

      Acceptance Criteria

      • Criterion 1 passes on two drivers.
      • Criterion 2 passes: restart mid-protocol, no lost completion.
      • A one-hour gate resumes with context on both drivers.
      • The 24-hour gate run is started and its start recorded.
      • Build and tests pass.

      Test Plan

      Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
      real; a fake clock does not test what the reaper does.



      What phase 9 actually left you — read the PR before starting

      #221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
      this seam. The ones that shape your work:

      • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
        in either direction.
        A keyed read that missed and then took the unkeyed one restores a
        cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
        one process; a turn dispatched to the wrong server succeeds.
      • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
        await there stalls delivery for every agent in every workspace including PTY-only ones. The
        synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
        ensureThreadBackendReady is CLI-only.
      • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
        its own command id.
        Two earlier attempts were wrong in ways worth not repeating: matching on
        message text let duplicate text recover a stale intent, and draining the whole journal replayed
        siblings' intents so they duplicated one agent over.
      • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
        no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
        receives no gate notice.
      • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
        shape in deliverToThread is the template; do not let each command grow its own copy.

      Live harness

      tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
      status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
      Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
      preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
      preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
      T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
      a provider.

      Standing rules for this program

      "I could not tell" must never be spelled the same way as "no." Reference implementations now in
      the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
      stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
      the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

      A green suite is evidence only about what it ran. Name which suites exist and which files each
      covers before quoting one. Five exist.

      Assert the mutation applied before trusting what it proves. A mutation check that silently
      no-ops produces a passing test, which looks exactly like the guard working.

      Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
      code did not provide, and two independent reviewers went straight to them. The corrected form now in
      the tree: argv heuristic, not proof of parentage.

      Not in scope

      #179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
      was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
      the program). Do not attempt either.

      Activity

      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        area/porchProtocol orchestrator

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , '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

          Spec 146 phase 10: full protocol on a second driver #235

          Description

          @pseudoseed

          Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
          it is unblocked.

          Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
          production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
          e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
          t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
          created against a real server
          while every in-memory test passed.

          The plan section is reproduced verbatim so it is not fetched by path.


          Phase 10: Full protocol on a second driver

          Dependencies: Phase 9

          Objective

          Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
          24-hour gate clock that Phase 14 depends on.

          Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
          deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

          Files to Create / Modify

          • packages/porch-driver/__tests__/full-protocol.test.ts
          • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
          • codev/research/146-driver-parity.md
          • codev/research/146-long-gate-evidence.md

          Deliverables

          • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
            that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
            assumed.
          • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
            event.
          • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
            146-driver-parity.md rather than worked around silently.
          • The 24-hour gate test is started in this phase and its evidence recorded when it
            completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
            here is the only way the schedule works.
          • Tests for this phase.

          Acceptance Criteria

          • Criterion 1 passes on two drivers.
          • Criterion 2 passes: restart mid-protocol, no lost completion.
          • A one-hour gate resumes with context on both drivers.
          • The 24-hour gate run is started and its start recorded.
          • Build and tests pass.

          Test Plan

          Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
          real; a fake clock does not test what the reaper does.



          What phase 9 actually left you — read the PR before starting

          #221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
          this seam. The ones that shape your work:

          • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
            in either direction.
            A keyed read that missed and then took the unkeyed one restores a
            cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
            one process; a turn dispatched to the wrong server succeeds.
          • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
            await there stalls delivery for every agent in every workspace including PTY-only ones. The
            synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
            ensureThreadBackendReady is CLI-only.
          • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
            its own command id.
            Two earlier attempts were wrong in ways worth not repeating: matching on
            message text let duplicate text recover a stale intent, and draining the whole journal replayed
            siblings' intents so they duplicated one agent over.
          • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
            no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
            receives no gate notice.
          • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
            shape in deliverToThread is the template; do not let each command grow its own copy.

          Live harness

          tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
          status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
          Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
          preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
          preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
          T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
          a provider.

          Standing rules for this program

          "I could not tell" must never be spelled the same way as "no." Reference implementations now in
          the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
          stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
          the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

          A green suite is evidence only about what it ran. Name which suites exist and which files each
          covers before quoting one. Five exist.

          Assert the mutation applied before trusting what it proves. A mutation check that silently
          no-ops produces a passing test, which looks exactly like the guard working.

          Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
          code did not provide, and two independent reviewers went straight to them. The corrected form now in
          the tree: argv heuristic, not proof of parentage.

          Not in scope

          #179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
          was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
          the program). Do not attempt either.

          Activity

          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            area/porchProtocol orchestrator

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , '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 \u003e 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

              Spec 146 phase 10: full protocol on a second driver #235

              Description

              @pseudoseed

              Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
              it is unblocked.

              Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
              production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
              e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
              t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
              created against a real server
              while every in-memory test passed.

              The plan section is reproduced verbatim so it is not fetched by path.


              Phase 10: Full protocol on a second driver

              Dependencies: Phase 9

              Objective

              Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
              24-hour gate clock that Phase 14 depends on.

              Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
              deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

              Files to Create / Modify

              • packages/porch-driver/__tests__/full-protocol.test.ts
              • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
              • codev/research/146-driver-parity.md
              • codev/research/146-long-gate-evidence.md

              Deliverables

              • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
                that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
                assumed.
              • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
                event.
              • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
                146-driver-parity.md rather than worked around silently.
              • The 24-hour gate test is started in this phase and its evidence recorded when it
                completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
                here is the only way the schedule works.
              • Tests for this phase.

              Acceptance Criteria

              • Criterion 1 passes on two drivers.
              • Criterion 2 passes: restart mid-protocol, no lost completion.
              • A one-hour gate resumes with context on both drivers.
              • The 24-hour gate run is started and its start recorded.
              • Build and tests pass.

              Test Plan

              Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
              real; a fake clock does not test what the reaper does.



              What phase 9 actually left you — read the PR before starting

              #221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
              this seam. The ones that shape your work:

              • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
                in either direction.
                A keyed read that missed and then took the unkeyed one restores a
                cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
                one process; a turn dispatched to the wrong server succeeds.
              • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
                await there stalls delivery for every agent in every workspace including PTY-only ones. The
                synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
                ensureThreadBackendReady is CLI-only.
              • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
                its own command id.
                Two earlier attempts were wrong in ways worth not repeating: matching on
                message text let duplicate text recover a stale intent, and draining the whole journal replayed
                siblings' intents so they duplicated one agent over.
              • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
                no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
                receives no gate notice.
              • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
                shape in deliverToThread is the template; do not let each command grow its own copy.

              Live harness

              tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
              status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
              Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
              preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
              preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
              T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
              a provider.

              Standing rules for this program

              "I could not tell" must never be spelled the same way as "no." Reference implementations now in
              the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
              stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
              the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

              A green suite is evidence only about what it ran. Name which suites exist and which files each
              covers before quoting one. Five exist.

              Assert the mutation applied before trusting what it proves. A mutation check that silently
              no-ops produces a passing test, which looks exactly like the guard working.

              Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
              code did not provide, and two independent reviewers went straight to them. The corrected form now in
              the tree: argv heuristic, not proof of parentage.

              Not in scope

              #179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
              was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
              the program). Do not attempt either.

              Activity

              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                area/porchProtocol orchestrator

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , '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

                  Spec 146 phase 10: full protocol on a second driver #235

                  Description

                  @pseudoseed

                  Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
                  it is unblocked.

                  Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
                  production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
                  e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
                  t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
                  created against a real server
                  while every in-memory test passed.

                  The plan section is reproduced verbatim so it is not fetched by path.


                  Phase 10: Full protocol on a second driver

                  Dependencies: Phase 9

                  Objective

                  Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
                  24-hour gate clock that Phase 14 depends on.

                  Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
                  deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

                  Files to Create / Modify

                  • packages/porch-driver/__tests__/full-protocol.test.ts
                  • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
                  • codev/research/146-driver-parity.md
                  • codev/research/146-long-gate-evidence.md

                  Deliverables

                  • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
                    that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
                    assumed.
                  • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
                    event.
                  • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
                    146-driver-parity.md rather than worked around silently.
                  • The 24-hour gate test is started in this phase and its evidence recorded when it
                    completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
                    here is the only way the schedule works.
                  • Tests for this phase.

                  Acceptance Criteria

                  • Criterion 1 passes on two drivers.
                  • Criterion 2 passes: restart mid-protocol, no lost completion.
                  • A one-hour gate resumes with context on both drivers.
                  • The 24-hour gate run is started and its start recorded.
                  • Build and tests pass.

                  Test Plan

                  Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
                  real; a fake clock does not test what the reaper does.



                  What phase 9 actually left you — read the PR before starting

                  #221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
                  this seam. The ones that shape your work:

                  • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
                    in either direction.
                    A keyed read that missed and then took the unkeyed one restores a
                    cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
                    one process; a turn dispatched to the wrong server succeeds.
                  • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
                    await there stalls delivery for every agent in every workspace including PTY-only ones. The
                    synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
                    ensureThreadBackendReady is CLI-only.
                  • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
                    its own command id.
                    Two earlier attempts were wrong in ways worth not repeating: matching on
                    message text let duplicate text recover a stale intent, and draining the whole journal replayed
                    siblings' intents so they duplicated one agent over.
                  • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
                    no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
                    receives no gate notice.
                  • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
                    shape in deliverToThread is the template; do not let each command grow its own copy.

                  Live harness

                  tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
                  status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
                  Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
                  preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
                  preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
                  T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
                  a provider.

                  Standing rules for this program

                  "I could not tell" must never be spelled the same way as "no." Reference implementations now in
                  the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
                  stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
                  the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

                  A green suite is evidence only about what it ran. Name which suites exist and which files each
                  covers before quoting one. Five exist.

                  Assert the mutation applied before trusting what it proves. A mutation check that silently
                  no-ops produces a passing test, which looks exactly like the guard working.

                  Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
                  code did not provide, and two independent reviewers went straight to them. The corrected form now in
                  the tree: argv heuristic, not proof of parentage.

                  Not in scope

                  #179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
                  was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
                  the program). Do not attempt either.

                  Activity

                  Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    area/porchProtocol orchestrator

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , '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

                      Spec 146 phase 10: full protocol on a second driver #235

                      Description

                      @pseudoseed

                      Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
                      it is unblocked.

                      Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
                      production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
                      e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
                      t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
                      created against a real server
                      while every in-memory test passed.

                      The plan section is reproduced verbatim so it is not fetched by path.


                      Phase 10: Full protocol on a second driver

                      Dependencies: Phase 9

                      Objective

                      Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
                      24-hour gate clock that Phase 14 depends on.

                      Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
                      deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

                      Files to Create / Modify

                      • packages/porch-driver/__tests__/full-protocol.test.ts
                      • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
                      • codev/research/146-driver-parity.md
                      • codev/research/146-long-gate-evidence.md

                      Deliverables

                      • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
                        that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
                        assumed.
                      • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
                        event.
                      • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
                        146-driver-parity.md rather than worked around silently.
                      • The 24-hour gate test is started in this phase and its evidence recorded when it
                        completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
                        here is the only way the schedule works.
                      • Tests for this phase.

                      Acceptance Criteria

                      • Criterion 1 passes on two drivers.
                      • Criterion 2 passes: restart mid-protocol, no lost completion.
                      • A one-hour gate resumes with context on both drivers.
                      • The 24-hour gate run is started and its start recorded.
                      • Build and tests pass.

                      Test Plan

                      Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
                      real; a fake clock does not test what the reaper does.



                      What phase 9 actually left you — read the PR before starting

                      #221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
                      this seam. The ones that shape your work:

                      • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
                        in either direction.
                        A keyed read that missed and then took the unkeyed one restores a
                        cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
                        one process; a turn dispatched to the wrong server succeeds.
                      • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
                        await there stalls delivery for every agent in every workspace including PTY-only ones. The
                        synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
                        ensureThreadBackendReady is CLI-only.
                      • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
                        its own command id.
                        Two earlier attempts were wrong in ways worth not repeating: matching on
                        message text let duplicate text recover a stale intent, and draining the whole journal replayed
                        siblings' intents so they duplicated one agent over.
                      • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
                        no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
                        receives no gate notice.
                      • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
                        shape in deliverToThread is the template; do not let each command grow its own copy.

                      Live harness

                      tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
                      status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
                      Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
                      preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
                      preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
                      T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
                      a provider.

                      Standing rules for this program

                      "I could not tell" must never be spelled the same way as "no." Reference implementations now in
                      the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
                      stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
                      the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

                      A green suite is evidence only about what it ran. Name which suites exist and which files each
                      covers before quoting one. Five exist.

                      Assert the mutation applied before trusting what it proves. A mutation check that silently
                      no-ops produces a passing test, which looks exactly like the guard working.

                      Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
                      code did not provide, and two independent reviewers went straight to them. The corrected form now in
                      the tree: argv heuristic, not proof of parentage.

                      Not in scope

                      #179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
                      was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
                      the program). Do not attempt either.

                      Activity

                      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        area/porchProtocol orchestrator

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , '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

                          Spec 146 phase 10: full protocol on a second driver #235

                          Description

                          @pseudoseed

                          Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
                          it is unblocked.

                          Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
                          production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
                          e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
                          t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
                          created against a real server
                          while every in-memory test passed.

                          The plan section is reproduced verbatim so it is not fetched by path.


                          Phase 10: Full protocol on a second driver

                          Dependencies: Phase 9

                          Objective

                          Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
                          24-hour gate clock that Phase 14 depends on.

                          Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
                          deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

                          Files to Create / Modify

                          • packages/porch-driver/__tests__/full-protocol.test.ts
                          • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
                          • codev/research/146-driver-parity.md
                          • codev/research/146-long-gate-evidence.md

                          Deliverables

                          • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
                            that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
                            assumed.
                          • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
                            event.
                          • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
                            146-driver-parity.md rather than worked around silently.
                          • The 24-hour gate test is started in this phase and its evidence recorded when it
                            completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
                            here is the only way the schedule works.
                          • Tests for this phase.

                          Acceptance Criteria

                          • Criterion 1 passes on two drivers.
                          • Criterion 2 passes: restart mid-protocol, no lost completion.
                          • A one-hour gate resumes with context on both drivers.
                          • The 24-hour gate run is started and its start recorded.
                          • Build and tests pass.

                          Test Plan

                          Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
                          real; a fake clock does not test what the reaper does.



                          What phase 9 actually left you — read the PR before starting

                          #221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
                          this seam. The ones that shape your work:

                          • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
                            in either direction.
                            A keyed read that missed and then took the unkeyed one restores a
                            cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
                            one process; a turn dispatched to the wrong server succeeds.
                          • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
                            await there stalls delivery for every agent in every workspace including PTY-only ones. The
                            synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
                            ensureThreadBackendReady is CLI-only.
                          • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
                            its own command id.
                            Two earlier attempts were wrong in ways worth not repeating: matching on
                            message text let duplicate text recover a stale intent, and draining the whole journal replayed
                            siblings' intents so they duplicated one agent over.
                          • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
                            no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
                            receives no gate notice.
                          • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
                            shape in deliverToThread is the template; do not let each command grow its own copy.

                          Live harness

                          tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
                          status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
                          Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
                          preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
                          preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
                          T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
                          a provider.

                          Standing rules for this program

                          "I could not tell" must never be spelled the same way as "no." Reference implementations now in
                          the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
                          stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
                          the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

                          A green suite is evidence only about what it ran. Name which suites exist and which files each
                          covers before quoting one. Five exist.

                          Assert the mutation applied before trusting what it proves. A mutation check that silently
                          no-ops produces a passing test, which looks exactly like the guard working.

                          Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
                          code did not provide, and two independent reviewers went straight to them. The corrected form now in
                          the tree: argv heuristic, not proof of parentage.

                          Not in scope

                          #179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
                          was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
                          the program). Do not attempt either.

                          Activity

                          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            area/porchProtocol orchestrator

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , '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

                              Spec 146 phase 10: full protocol on a second driver #235

                              Description

                              @pseudoseed

                              Spec 146 phase 10. Its premise is now true rather than assumed, which is why it was held and why
                              it is unblocked.

                              Phase 10 is "full protocol on a second driver", and "second" presumes a first driver works in
                              production. It did not. #179 items 3 and 4 established it live tonight (PR #221, merged as
                              e241326a1), and item 3 was not merely unrun — createArchitectThread sent branch: '', which
                              t3code refuses as NullOr(TrimmedNonEmptyString), so no architect thread could ever have been
                              created against a real server
                              while every in-memory test passed.

                              The plan section is reproduced verbatim so it is not fetched by path.


                              Phase 10: Full protocol on a second driver

                              Dependencies: Phase 9

                              Objective

                              Run a complete protocol end to end with no PTY involved, on two provider drivers, and start the
                              24-hour gate clock that Phase 14 depends on.

                              Only Codex was exercised in the spike. Success criterion 10 requires a second driver before
                              deletion, and this phase is where a driver-specific failure surfaces while it is still cheap.

                              Files to Create / Modify

                              • packages/porch-driver/__tests__/full-protocol.test.ts
                              • packages/porch-driver/src/drivers/ — per-driver quirks, if any are found.
                              • codev/research/146-driver-parity.md
                              • codev/research/146-long-gate-evidence.md

                              Deliverables

                              • A complete BUGFIX protocol on a t3code thread: spawn, phases, checks between turns, a gate
                                that pauses at least one hour, PR, merge. No PTY code path runs, asserted rather than
                                assumed.
                              • Porch restarts mid-protocol, resubscribes with afterSequence, and loses no completion
                                event.
                              • The same run on a second, non-Codex driver. Any behavioural difference is recorded in
                                146-driver-parity.md rather than worked around silently.
                              • The 24-hour gate test is started in this phase and its evidence recorded when it
                                completes. It gates Phase 13, so it must be running well before Phase 13 begins; starting it
                                here is the only way the schedule works.
                              • Tests for this phase.

                              Acceptance Criteria

                              • Criterion 1 passes on two drivers.
                              • Criterion 2 passes: restart mid-protocol, no lost completion.
                              • A one-hour gate resumes with context on both drivers.
                              • The 24-hour gate run is started and its start recorded.
                              • Build and tests pass.

                              Test Plan

                              Integration, long-running, against a live server. The one-hour and 24-hour gates are elapsed for
                              real; a fake clock does not test what the reaper does.



                              What phase 9 actually left you — read the PR before starting

                              #221 is 22+ defects across ten review rounds. Its verification doc and PR body are the map of
                              this seam. The ones that shape your work:

                              • The engine registry is keyed by canonical workspace root, and the unkeyed slot is NOT a fallback
                                in either direction.
                                A keyed read that missed and then took the unkeyed one restores a
                                cross-workspace misroute one indirection further away. Tower drains mail for every workspace from
                                one process; a turn dispatched to the wrong server succeeds.
                              • Nothing on MailboxDrainer.tick may be awaited. The tick is sequential across agents, so any
                                await there stalls delivery for every agent in every workspace including PTY-only ones. The
                                synchronous requestThreadBackend, returning a state union rather than a promise, is the pattern.
                                ensureThreadBackendReady is CLI-only.
                              • A mailbox row's intent carries its row id (ref) and recovery replays only that intent, under
                                its own command id.
                                Two earlier attempts were wrong in ways worth not repeating: matching on
                                message text let duplicate text recover a stale intent, and draining the whole journal replayed
                                siblings' intents so they duplicated one agent over.
                              • --no-enter is terminally refused on threadsthread.turn.start IS the submit, so there is
                                no composer to stage into. Porch gate notifications use --no-enter, so a thread-backed architect
                                receives no gate notice.
                              • afx interrupt and afx cleanup still throw on the thread path (Thread path: a process-global spawn factory in Tower, interrupt/cleanup still broken, and two smaller seams #227). The init-plus-attach
                                shape in deliverToThread is the template; do not let each command grow its own copy.

                              Live harness

                              tools/t3-server/t3-server.mjsacquire, verify, start, restart, ready, stop,
                              status. T3_NODE must be an absolute interpreter path; the harness refuses to inherit its
                              Node from PATH and reports NO_INTERPRETER: could not check rather than guessing. restart
                              preserves the data dir; start wipes it, and NO_DATA_TO_KEEP exits UNDETERMINED so "nothing to
                              preserve" cannot read as a pass or a failure. The live test takes T3_LIVE_HARNESS /
                              T3_LIVE_MODEL, so a criterion about threads can be run under any driver — it is not a claim about
                              a provider.

                              Standing rules for this program

                              "I could not tell" must never be spelled the same way as "no." Reference implementations now in
                              the tree: found | none | unknown (project lookup), known: false only on spawn error or non-empty
                              stderr (lsof — the exit code alone cannot separate "nothing is listening" from "I could not run
                              the check"), UNDETERMINED as its own exit, and UNCONFIRMED as a client band distinct from refused.

                              A green suite is evidence only about what it ran. Name which suites exist and which files each
                              covers before quoting one. Five exist.

                              Assert the mutation applied before trusting what it proves. A mutation check that silently
                              no-ops produces a passing test, which looks exactly like the guard working.

                              Write what makes a claim true, or write the limit. Four comments in #221 asserted guarantees the
                              code did not provide, and two independent reviewers went straight to them. The corrected form now in
                              the tree: argv heuristic, not proof of parentage.

                              Not in scope

                              #179 items 6 and 7 remain held by the architect and unticked: the concurrency measurement (fleet RSS
                              was 2.4 GB with one builder) and the /arch-save runbook (the only architect here is the one running
                              the program). Do not attempt either.

                              Activity

                              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                area/porchProtocol orchestrator

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions