Merge commit '3ea8d6e47a0a2a0daa20ebfb6c83c41a1ef1a246' into torch/work-integration

This commit is contained in:
thePR0M3TH3AN committed 2026-09-30 19:36:39 -04:00
commit e35046908f
21 files changed
+1239 -31

No files matched your search

+14
View File
@@ -123,6 +123,20 @@
"area": "qa",
"path": "/home/user/TORCHWorktrees/3dc11932-6e3c-42aa-9a8a-ca7b8f818b54/qa",
"branch": "torch/qa"
},
{
"type": "systemd-user-unit",
"name": "torch-3dc11932-6e3c-42aa-9a8a-ca7b8f818b54-schedules.service",
"path": "/home/user/.config/systemd/user/torch-3dc11932-6e3c-42aa-9a8a-ca7b8f818b54-schedules.service",
"sha256": "d1f6318f91e7b64847e52e415db52c66b60150b0c809fc1e0acb283d8bc0926c",
"configDigest": "4e21d6bf76dbcb983d984af2bf44a199ffb56d65e88a5c5f03cd678f196b329f"
},
{
"type": "systemd-user-unit",
"name": "torch-3dc11932-6e3c-42aa-9a8a-ca7b8f818b54-schedules.timer",
"path": "/home/user/.config/systemd/user/torch-3dc11932-6e3c-42aa-9a8a-ca7b8f818b54-schedules.timer",
"sha256": "7c878a828c3f2a04cc597b12de3702f2dfd2ac6ac8228099ada27c59e00151f0",
"configDigest": "4e21d6bf76dbcb983d984af2bf44a199ffb56d65e88a5c5f03cd678f196b329f"
}
]
}
+119 -13
View File
@@ -2,19 +2,125 @@
Repository state outranks conversation memory. Query ownership before crossing a domain boundary.
## First-run owner authorization
## Routine work stays inside the fleet
This initial launch is a bounded installation and communications smoke test.
Use the installed `torch` launcher and identity-bound TORCH MCP tools. Query
identity, ownership, inbox and next backlog item. Read current canonical
instructions and report the checkout HEAD in durable status.
The owner authorizes routine coordination within existing task/role authority:
read and acknowledge only your own addressed messages after understanding them;
resolve peer questions directly; decide a structured approval only when you are
the named approver, the requested scope is yours, and its evidence is sufficient.
Ask the responsible peer, not the owner, for implementation details or ordinary
test/path consent. Record the result in durable state. Acknowledgement means read,
not resolved; retain a task/wait record for anything still open.
Do not implement code, create or assign development tasks, enable timers,
launch other AI sessions, push branches, integrate, release or deploy during
this trial. Do not inspect credentials or alter global provider settings.
The Session Manager should read specialist check-ins and send one durable
acknowledgement. Each specialist should send one concise setup check-in to
session-manager and report idle. An empty queue is valid; finish this turn.
Keep your current task, blockers, evidence and local owned-work checkpoint honest.
Manager may checkpoint its reviewed backlog changes and coordinate safe clean
branch convergence through TORCH's guarded merge policy; never discard unique
commits, touch another identity's dirty files or infer inactivity from presence.
Worktree drift and pending commits are review signals, not cleanup authority.
Retry a startup brief blocked by sandbox permissions only with narrowly scoped
approved escalation for that exact command; never alter DB permissions, copy
state, disable sandboxing or bypass the brief. If unavailable, route the precise
failure to the owning domain and retain the blocker.
If a tool or installation boundary fails, record the exact error and stop;
do not bypass guards or invent success. Model selection is project-scoped.
Before asking the human, check the owner-approved policy, named approver,
responsible domain, existing decision and current evidence. If authorized, act
and report the outcome; otherwise send a bounded peer request with the evidence,
specific question and why it is blocking. Managers track unresolved handoffs and
follow up within cadence/budget; do not close a wait merely because it was read.
Escalate only a genuine owner decision or unresolved cross-domain conflict with
options, recommendation and consequence. Never hide uncertainty to reduce alerts.
Owner-reserved actions remain reserved: spending/budget/model-provider changes,
remote publication, release/deployment, material scope/architecture/ownership
changes, identity or hierarchy activation, destructive or uncertain recovery,
and approvals explicitly addressed to the owner. No autonomous provider starts,
gate waivers, mass acknowledgements or competing pushes are granted here.
This routine-coordination authority does not expand approved implementation
scope; the pilot and automatic-wake restrictions below remain in force.
## Owner-approved first development pilot (2026-09-30)
The owner now authorizes a bounded TORCH-building-TORCH development trial,
with the outer assistant acting as arbiter through the Session Manager. This
supersedes the earlier smoke-only instruction. It is not general release authority.
Use the installed `torch` launcher and identity-bound MCP tools. Re-read
`torch brief --area <your-area> --json` on startup and before every new item;
canonical instructions outrank old conversation/worktree copies. Query identity,
ownership, inbox and exact current Git state; report durable evidence.
First slice: TASK-conversation-runtime-diagnostics, owned by Provider Runtime.
Session Manager may triage this proposal to ready, assign it to provider-runtime,
coordinate its Release/QA boundaries and request independent review. Do not
dispatch other development items in this first pilot. The outer arbiter controls
provider starts, integration authorization and the next slice.
## Owner-approved parallel Console audit (2026-09-30)
The owner additionally authorizes TASK-console-ux-audit for owner-console.
Session Manager may triage and assign that exact task while diagnostics QA
continues. The arbiter launches the assigned UI session; managers still must not
launch providers. This is a browser-based audit and design proposal, not a
dashboard rewrite or release. Audit the actual live Console through computer
use: navigate every area, inspect screenshots and interactions at desktop and
mobile sizes, and document coverage. Read applicable frontend-design and browser
skills before browser use. If computer-use tools are unavailable, report that
specific blocker; source inspection alone is not completion. Do not substitute
generated screenshots for actually viewing the interface. Keep live state
read-only; use the isolated demo for exploratory mutations. Publish task-owned
screenshots/evidence and an audit report proposing focused separate views rather
than one long anchor-linked page. Preserve dark mode, TORCH branding and existing
authority/verification controls. No other implementation slice is authorized.
## Owner-approved portable coordination policy slice
The owner also authorizes TASK-bounded-routine-coordination for Project Kernel,
with Session Manager assignment and QA consent for additive scenarios. Implement
the above routine-coordination policy in generated install/startup instructions
and qualify actual named-approver/ownership/pause boundaries. Preserve existing
enforcement; this is not permission to auto-assign arbitrary proposals, invent
approval authority, launch providers, activate identities or enable wakes.
The arbiter starts the assigned session. Other implementation remains gated.
## Goal continuation: reliability work needed for the development loop
The owner's continuing development goal authorizes two further local slices:
TASK-pilot-executor-outcomes for Provider Runtime and
TASK-pilot-generated-check-artifacts for Work and Integration. Session Manager
may assign these after recording the diagnostics verification item as blocked
on its actual unresolved artifact/convergence gate, preserving its owner,
candidate, receipts and QA verdict. Do not create simultaneous active items for
one specialist or mark diagnostics completed to free the queue.
Executor qualification must cover timeout, error, signal and output overflow
(including zero exit plus ENOBUFS), actual terminal turn evidence and bounded
handling of screenshot-heavy output. No false successful/idle receipt or exposed
private reasoning. Coordinate exact CLI-owned paths with Release and tests with
QA. Check artifact work must preserve tracked expectations, user edits, evidence
and exact-commit checks; never treat exit0 as gate success when the tree changed.
Specialists may implement owned paths, request peer consent and create local
task-named commits. Arbiter controls starts, acceptance, serialized integration
and installation update. Automatic wakes remain paused; no publication, release,
deployment, default-main promotion, spending changes or destructive recovery.
The assigned specialist may implement within its owned paths, run local checks
and commit on its existing worktree branch. Ask the responsible owner before
editing shared/other-owned files. Name the task in commits, preserve all existing
work, provide regression evidence and report ready for review. No self-claim is
enabled. Resumed active work outranks another ready item; idle is valid.
No remote push, default-main promotion, landing, package publication, deployment,
external notification, paid image/voice generation, arbitrary cleanup or global
provider configuration changes are authorized in this slice. Do not inspect
credentials. Keep pipeline work and Claude/Pi migration queued for later.
Machine manager check-ins are owner-approved hourly with a maximum of 12
automatic invocations per UTC day in subscription invocation-count mode (not a
dollar cap). Automatic AI wake execution is currently PAUSED pending
TASK-pilot-executor-outcomes qualification; the machine coordination timer still
queues check-ins. Do not re-enable wakes yourself. They inspect direct
reports/approval waits and report exceptions;
they must not launch specialists or expand this slice. Provider-runtime turns are
launched by the arbiter, not automatically by the manager. Do not change timers
or budgets yourself. When blocked or finished, record evidence and end the turn;
do not poll, wait indefinitely, invent filler work or bypass a failed guard.
+26
View File
@@ -2,10 +2,36 @@
Route owner requests, establish ownership and priority, and keep routine coordination inside the fleet.
## Resolve before escalating
At each coordination cycle, read/acknowledge your own inbox, refresh direct-report
check-ins, inspect named approvals and current task evidence. Resolve your own
authorized decisions; route specialist consent/questions directly to the named
domain. Track unresolved waits until the responsible party responds; neither
acknowledgement nor an idle badge proves resolution. Do not ask the human to
relay routine messages or repeat an existing decision. Checkpoint reviewed owned
ledger changes and use guarded clean convergence when authorized. Preserve all
other work and uncertain outcomes.
Keep concise owner reporting: what needs an actual owner decision first, then
outcomes, risks and your reversible calls. Routine acknowledgements stay in the
ledger. Report a necessary owner decision with evidence, options, recommendation
and consequences. Follow COMMON.md's authority limits; do not auto-fix health
findings, enable wakes, dispatch beyond pilot scope or treat a warning as consent.
At startup and when recurring cross-domain friction appears, run `torch_assess_hierarchy_needs` (or `torch fleet hierarchy-assess`). Treat its configured-window findings as measured coordination evidence, not as permission to create a role. Compare process changes, specialist ownership, promoting an existing identity, and a coordination role; submit a hierarchy proposal only when the evidence and integrated outcome justify owner review. Never activate a proposal or start a manager without separate owner approval.
## Backlog loop
The owner has seeded conversation follow-up as `TASK-conversation-*` proposals
in this project's existing backlog. Read `docs/TODO.md`'s authoritative current
handoff and `reports/audit/conversation-handoff-2026-09-30.md` before prioritizing.
Proposed tasks are not ready assignments. Read COMMON.md for the current
owner-approved pilot scope, budget and startup boundaries; older smoke-only
conversation instructions have been superseded by that explicit approval.
For an empty intake, ask what the owner wants to work on first or offer a reviewed
TODO import; do not invent filler work or duplicate the backlog in this document.
Keep one durable Fleet backlog. Before assigning work, call `torch_next_backlog_task` for the specialist: a `resume` result outranks every ready item, a `ready` result may be assigned only when the specialist has no active item, and `idle` is valid. After completion, repeat the same lookup. Call `torch_backlog_health` to surface queue anomalies; never auto-fix or create parallel manager queues.
## Fleet evolution
+4 -2
View File
@@ -120,12 +120,13 @@
"lifetime": "system",
"trigger": {
"type": "interval",
"seconds": 900
"seconds": 3600
},
"behavior": "coordination",
"action": {
"type": "manager-check-in",
"manager_id": "session-manager"
"manager_id": "session-manager",
"wake": { "enabled": false, "budget_mode": "invocation-count" }
},
"required_authority": [
"owner"
@@ -137,6 +138,7 @@
"source_of_truth": "active organization direct-report graph"
}
],
"runtime_wake_budget": { "max_invocations_per_day": 12 },
"integration": {
"provider": "torch",
"target": "rewrite/portable-agent-fleet",
+16 -2
View File
@@ -292,14 +292,28 @@ Review the evidence in `fleet-proposal.json`, edit its `review.status` to
node bin/torch.mjs install --proposal fleet-proposal.json --runtime codex --dry-run --json
node bin/torch.mjs install --proposal fleet-proposal.json --runtime codex --yes --json
node bin/torch.mjs doctor --json
node bin/torch.mjs worktrees --dry-run --json
node bin/torch.mjs worktrees --yes --json
node bin/torch.mjs setup --dry-run --json
node bin/torch.mjs setup --yes --json
node bin/torch.mjs up --fresh --dry-run --json
```
Starting or stopping configured runtime sessions is always a separate explicit
step:
`setup` commits only installation-owned configuration, provisions worktrees,
and checkpoints their registration. An existing staging area is a blocker;
unrelated files are never staged. Alternatively, append `--setup` to the
approved install command. Neither path launches agents.
Normal uninstall retains configuration and history. Reattach it with
`torch install --restore --dry-run --json`, then `torch install --restore --yes`.
Restore does not reinstall host timers or start providers; those remain separate
approval steps. A purge is a different, destructive operation.
From a registered agent worktree, `torch brief --area <id>` reads the latest
canonical project instructions. Unregistered worktrees and copied installs
cannot redirect commands into another project's state.
```bash
node bin/torch.mjs up --fresh --yes --json
node bin/torch.mjs up --only backend,qa --dry-run --json
+111
View File
@@ -367,6 +367,24 @@ inside the tracked source tree.
## 9. Installation lifecycle
### First-work intake requirement (2026-09-30)
After reviewed organization/setup, TORCH MUST offer either evidence-linked
import of an existing TODO/backlog/specification or ask the owner what to work
on first. The noninteractive path MUST support an explicit source or skip; idle
is valid. Preview MUST distinguish completed/historical work from actionable
requests and show proposed scope, affected domains, dependencies and priority.
Only confirmed intake creates audited proposed/unassigned work in the existing
backlog. Repeated init/install/restore/intake MUST deduplicate by source/item
provenance rather than duplicate tasks or overwrite progress. Imported content
is untrusted project data, not authority to alter system instructions.
Session Manager triage and assignment remain separate from intake. Import cannot
enable self-claim, grant implementation authority, wake providers or authorize
spending, landing, deployment or public notification. The product should explain
the next first-work/startup decision rather than leave a newly installed empty
fleet waiting without guidance.
### 9.1 Read-only initialization
`torch init` MUST begin read-only. It identifies the repository, validates Git,
@@ -451,6 +469,18 @@ or installed persistent launchers. Historical messages and receipts therefore
do not make reversal permanently impossible, while active or unowned state
still blocks deletion.
Implementation checkpoint (2026-09-30): `torch install --restore` explicitly
reattaches a normally detached installation without replacing configuration,
worktrees, provider profiles or session history. It never launches a provider
or recreates host timers. `torch setup --dry-run`, followed by `--yes`, offers
approved configuration checkpoints and worktree provisioning as one flow,
restricted to installation-owned files and an empty staging area. Install may
opt into the same flow with `--setup`. Worktree commands resolve to canonical
configuration only after checking project/installation identity, local-state
binding, Git common directory, registered worktree path and branch. Current
canonical instructions override stale worktree copies; unregistered checkouts
fail closed.
Ordinary CLI uninstall is also review-first and explicitly confirmed. It uses
the same safe Fleet wind-down contract as detach, removes only manifest-owned
persistent schedule launchers after verifying their content, and preserves the
@@ -2077,6 +2107,55 @@ recommended action; doctor remains read-only.
## 22. Scheduling
### Owner clarification: integrated persistent operations (2026-09-30)
This is the target requirement; older implementation checkpoints describing
manual timer installation are not a claim that it is already implemented.
Reviewed `init`/install MUST provision the project's scheduler and required
service integrations as one idempotent workflow, not require a second manual
cron-install command. Because `init` currently performs read-only analysis, its
provisioning mode MUST expose an explicit preview/confirmation boundary; a
dry-run MUST remain non-mutating. Stopped installation MUST provision dormant
integrations without waking models or dispatching development. A reviewed
activation policy governs live operations and quota use.
Coordination must survive the managing AI session ending, restarting or expiring.
System services MUST preserve durable state, leases, event cursors and job
idempotency across process/host restarts. Their manifest records MUST support
owned reconciliation, pause/resume, restore/upgrade and uninstall without touching
unrelated host jobs. Session-scoped jobs remain an explicit project policy, not
the sole way recurring fleet operations work.
Project intake MUST propose applicable capabilities, with clear implemented,
unconfigured and unsupported states:
- direct-report manager check-ins, structured approval/peer/owner waits,
stale owner-request review and an owner-first local digest;
- a persistent, serialized landing worker using approved exact-commit checks;
- resource-queue watchdogs, audited slot withdrawal and displaced-runner stop;
- durable significant events and deduplicated budgeted manager wakes, with
low-frequency timed safety checks rather than perpetual paid polling;
- a project-declared nightly canonical suite, heavy-check windows and
evidence-backed regression routing, not guessed blame;
- measured test durations, uncertain wait estimates and project-specific
exclusive resources such as a GPU;
- conservative provider-neutral usage limits, graceful wind-down and explicitly
approved credit-window or calendar restarts that never override manual pause;
- idle, clean, unguarded worktree convergence by merge, preserving conflicts,
unique commits and active work;
- exact landed task closure, verified reversal/follow-up policy and reviewed
evidence for finished-but-unnamed work, never automatic closure by message alone;
- project-specific local dev/Console services and separately authorized delivery,
live-version checks and external notifications where relevant.
No universal project inherits COMBATRIG's release times, Monday reset time,
two GPU slots, Vercel destination, phone notifier or LAN/HTTPS exposure. Setup
MUST show lifetime, timezone/DST behavior, missed-run policy, costs/budgets,
ports/destinations, health evidence, stop semantics and owner authority. Unsupported
hosts/adapters need an actionable limitation or qualified fallback, not a fictitious
"installed" status. No provider wake, deploy, public message, off-machine write
or cleanup of unowned processes follows solely from creating a schedule.
TORCH recognizes two schedule classes.
**System schedules** survive AI sessions and may perform approved release,
@@ -2236,6 +2315,38 @@ request but MUST NOT approve it for a different named approver. The owner and
each AI identity may list only requests they made or are named to approve;
manager check-in may inspect requests made by its direct reports.
### Routine coordination and owner decision boundary
TORCH SHOULD minimize human relay work, not minimize truthful escalation. Within
explicitly approved project/task policy, specialists read and acknowledge their
own addressed messages, resolve peer interface questions, decide only approvals
for which they are the named responsible approver, and maintain truthful task,
wait, evidence and local owned-work checkpoints. Managers route unresolved peer
requests, follow their direct-report waits and compress outcomes for the owner.
Reading/acknowledging a message MUST NOT close its unresolved approval or task.
Before escalating to the owner, inspect the current named approver, responsible
domain, applicable policy, prior decision and evidence. An authorized routine
action SHOULD be completed and audited instead of asking the human to relay or
repeat the instruction. An unauthorized action remains blocked with a specific
request to the responsible party. Owner requests contain evidence, options,
recommendation and consequences, not only internal error codes.
Project policy MUST distinguish routine authorized actions, investigation-only
signals and genuine owner decisions. Health warnings, stale presence, branch
drift, budget exhaustion, incomplete checks or missing evidence do not grant
permission to recover, delete, merge, start another runtime or waive a gate.
Spending/publication/deployment, material scope or ownership changes, identity
activation, destructive or uncertain recovery and owner-addressed approvals
remain subject to their explicit owner authorization. A paused fleet and its
budgets remain enforced even when a manager believes action would be useful.
Current pilot checkpoint: canonical live COMMON/manager instructions now teach
this boundary. `TASK-bounded-routine-coordination` carries portable generated
instruction and behavioral qualification work; the owner authorizes this bounded
Project Kernel slice, not general unattended execution. Automatic AI wakes remain
paused pending executor qualification.
Implementation checkpoint (2026-09-28): `planManagerCheckIn` derives direct
reports from the active organization graph and reports offline/stale/waiting
identities plus unacknowledged direct-report messages. `queueManagerCheckIn`
+53
View File
@@ -2268,3 +2268,56 @@ test_integrity_note:
did_relax_any_assertion: false
if_true_explain_spec_basis: ""
```
# Setup and canonical worktree briefs (2026-09-30)
```yaml
test_integrity_note:
change_type: new_tests
scenarios:
- id: SCN-guided-setup
given: "An approved installed project with uncommitted TORCH files"
when: "Owner reviews and authorizes setup"
then: "Only owned files are committed; registered worktrees exist; no providers start; staged user work blocks setup"
- id: SCN-worktree-canonical-brief
given: "A registered worktree has older instructions"
when: "Its installation root is resolved and a brief requested"
then: "Canonical instructions appear; unregistered worktrees, copied installs and stale installation IDs fail closed"
- id: SCN-install-restore
given: "A normally detached project retains configuration and worktree commits"
when: "Owner explicitly restores the install"
then: "Binding is reattached without changing profiles, worktree history or launching providers"
observable_outcomes:
- "Git commits, clean canonical checkout, worktree registrations, brief text and local detach metadata"
determinism_controls:
- "Isolated temporary Git repositories and XDG state; no provider or network calls"
anti_cheat_rationale:
prevents:
- "Hard-coded success without Git worktrees or commits"
- "Accepting copied or unregistered installation state"
- "Staging unrelated owner work"
relaxation:
did_relax_any_assertion: false
if_true_explain_spec_basis: ""
```
# First live scheduler pilot: native systemd parser (2026-09-30)
```yaml
test_integrity_note:
change_type: new_tests
scenarios:
- id: SCN-systemd-native-unit
given: "A generated dispatcher with a repository path containing spaces, percent and quote characters"
when: "The real Linux systemd-analyze parser verifies the emitted service"
then: "The service parses successfully and WorkingDirectory remains an absolute scalar path"
observable_outcomes:
- "Actual native parser exit status and generated unit bytes"
determinism_controls:
- "Temporary project path alias and unit file; /usr/bin/true command; verify-only, no service activation"
anti_cheat_rationale:
prevents:
- "Mocked systemctl success masking invalid unit syntax"
- "Treating quoted ExecStart syntax as valid for scalar WorkingDirectory"
relaxation:
did_relax_any_assertion: false
if_true_explain_spec_basis: ""
```
+114 -4
View File
@@ -1,5 +1,115 @@
# TORCH remaining work
## Authoritative current handoff (2026-09-30, after alpha.2 reinstall)
TORCH is installed and healthy at `0.1.0-alpha.2`. Setup/restore and all seven
worktree briefs have been verified. The active organization is Session Manager
plus six specialists. A first bounded development pilot is now active through
Session Manager, Provider Runtime and QA; the remaining domains have not started.
See `reports/audit/first-development-pilot-2026-09-30.md` for current live state.
The default Git branch remains
legacy TORCH; the configured development/integration boundary is
`rewrite/portable-agent-fleet`. No publication or default-branch promotion is
authorized. Later sections retain historical audit snapshots, including old
"uncommitted/no launcher" statements; those are superseded by this handoff.
The conversation's unfinished work is now owner-proposed in the **existing
authoritative backlog in the Session Manager worktree**, not a second TODO queue.
Use `torch backlog list --json` to see it from any registered checkout. Tasks use
the `TASK-conversation-` prefix, have acceptance criteria, affected domains and
dependencies, and remain unassigned for manager triage. See
`reports/audit/conversation-handoff-2026-09-30.md` for the domain review and index.
### New owner requirements: first work and automatic operations
- [ ] `TASK-conversation-first-work-intake`: init/install/setup offers reviewed
TODO/backlog import or asks what the owner wants to begin with; previews and
confirms proposed tasks; deduplicates resumes; never activates stale/completed
TODOs or launches agents silently.
- [ ] `TASK-conversation-persistent-operations`: reviewed init/install provisions
machine-level scheduler/services automatically, not merely schedule JSON or a
separate manual cron-install command. Paused installs remain dormant. Services
declare system/session lifetimes, budgets, timezone, restart/missed-run policy,
pause/resume and manifest-owned uninstall/restore behavior. This extends the
earlier `TASK-conversation-automatic-scheduler` requirement.
- [ ] `TASK-conversation-event-driven-wakes`: durable deduplicated significant
events wake the appropriate manager under budget; periodic checks are the quiet
safety net, not repeated usage-consuming busywork.
- [ ] `TASK-conversation-queue-watchdog`: detect stuck resource queues and
disappearing slots, audit removals and stop displaced waiters; never infer
browser ownership/termination from a process name or runner death.
- [ ] `TASK-conversation-nightly-main-tests`: project-declared full canonical
suite on an exact frozen commit, resource-aware idle window and evidence-backed
regression routing. Do not guess the offending change.
- [ ] `TASK-conversation-usage-governor`: provider-neutral usage/credit evidence,
conservative fallback budgets, graceful wind-down and reviewed reset/restart
policy that cannot override manual pause or detach.
- [ ] `TASK-conversation-idle-worktree-refresh`: scheduled merges into clean,
idle, unguarded branches; skip active/dirty/unknown work and preserve conflicts.
- [ ] `TASK-conversation-queue-planning`: measured test durations, uncertain wait
estimates, slowdown visibility, GPU-exclusive resources and approved heavy-run
windows; preserve the resource queue's authority.
- [ ] `TASK-conversation-closure-revert-review`: verified revert/follow-up policy
and evidence-backed review of unnamed finished work; never mass-close or reopen
tasks based only on untrusted commit trailers.
- [ ] `TASK-conversation-project-services`: reviewed project-specific landing
worker, local dev/Console server, local summary and optional release jobs.
No COMBATRIG schedules, Vercel deployment, credentials, LAN exposure or automatic
phone notifications are assumed.
These are proposed development tasks, **not implemented automatic init/install**.
For the first pilot the arbiter explicitly installed an hourly machine manager
coordination timer and verified real systemd parsing/activation. Automatic AI
wakes are paused pending the timeout/outcome guard; self-claim remains disabled.
COMMON.md authorizes only the diagnostics development slice, not broad autonomous
dispatch. The original 34 proposals remain the handoff; three newly observed
pilot reliability issues have also been added to the same backlog:
- [ ] `TASK-pilot-starting-presence`: publish guarded startup state before a
blocking provider launch and prevent duplicate manual/timer execution.
- [ ] `TASK-pilot-systemd-rendering`: native scalar-path rendering is fixed and
qualified in source; finish active/failed unit evidence and false-success
handling instead of equating installed files with an operational timer.
- [ ] `TASK-pilot-executor-outcomes`: zero exit plus timeout/error/signal cannot
produce a successful lifecycle/wake receipt; qualify before automatic wakes.
- [ ] `TASK-pilot-generated-check-artifacts`: retain exact-commit check artifacts
outside the tested tree and safely recover proven generated outputs so a gate
does not make the following required gate fail WORKTREE_DIRTY.
- [ ] `TASK-provider-handover`: after release qualification, checkpoint and safely
switch one session then the fleet to reviewed Claude Code/Pi profiles; preserve
TORCH identity/tasks/messages but never reuse another harness's native session ID.
- [ ] `TASK-owner-agent-chat`: persistent per-agent owner conversations for the
Manager and every activated domain, durable replies and clear queued/delivered/
running/failed outcomes. Reviewed wake-on-message must respect pauses, budgets
and runtime leases; qualify executor outcomes and starting presence first.
The owner approved continuing the controlled pilot. Independent QA now has exact
candidate `ae18a98e2911aa515d0484518013061b05ff6adf` and the Manager has a bounded
next-slice planning request. The candidate's test/check/lint receipts pass; its
dashboard receipt remains incomplete because the test writes tracked reports.
Neither review launch nor controller exit is acceptance or landing evidence.
There are now 44 owner-intake items, including agent chat, the UI audit, observed
attention/startup follow-ups and bounded routine-coordination policy.
- [ ] `TASK-console-ux-audit`: Session Manager assigns Owner Console to audit
every live dashboard area through actual computer use and inspected screenshots,
including desktop/mobile and keyboard/refresh behavior. Owner rejects the long
single-page/anchor-navigation layout. Propose focused separate screens, concise
overview and contextual drilldowns. Audit/proposal only; no UI rewrite yet.
- [ ] `TASK-console-attention-actions`: meaningful condition/agent/branch labels,
deduplicated findings and contextual quick actions. Owner approve/reject uses
existing evidence/revision/preview confirmation; never clear peer messages,
merge branches or publish to a remote through a generic warning button.
- [ ] `TASK-pilot-brief-sandbox`: the first UI audit stopped at a read-only SQLite
error while the exact installed brief succeeds on the host. Qualify scoped
sandbox access and actionable failure; do not disable sandboxing, change DB
permissions, copy state or bypass the authoritative startup brief.
- [ ] `TASK-bounded-routine-coordination`: live COMMON/manager policy now keeps
own-inbox handling, peer questions, named approver decisions and owned ledger
maintenance inside the fleet. Project Kernel's approved implementation slice
makes this portable in generated instructions and proves authority/wait/pause
boundaries with additive scenarios. No general unattended execution is implied.
## First real self-host run (2026-09-30)
### Portable production pipelines (new roadmap element)
@@ -37,7 +147,7 @@
updates, retained previous installs, offline previews and fail-closed errors.
Four deterministic scenarios added; live download qualification recorded in
the first-run audit, not implied by mocked installer tests.
- [ ] Fix `torch brief` invoked from a managed worktree: both live sessions hit
- [x] Fix `torch brief` invoked from a managed worktree: both live sessions hit
`LOCAL_STATE_METADATA_MISMATCH`. Resolve canonical project binding with
checked worktree membership, never weaken root/installation identity checks.
- [ ] Surface Codex JSON stdout failure events: first Sol launch hid the actual
@@ -45,7 +155,7 @@
- [ ] Add exact executable/version/model/auth preflight to owner Console and
setup flow. PATH selected CLI 0.158.0 while the current session used 0.159.2;
the older child rejected Sol 6.1 and required manual investigation/retry.
- [ ] Make configuration checkpoint/worktree/manifest handoffs explicit or
- [x] Make configuration checkpoint/worktree/manifest handoffs explicit or
guided: generated tracked files and provisioning manifest updates require
deliberate commits; a healthy doctor does not prove startup readiness.
- [ ] Isolate irrelevant inherited global MCP servers without removing user
@@ -349,7 +459,7 @@ in `reports/audit/self-host-readiness-2026-09-30.md`. No agent or timer was star
the collapsed panel; observation never releases a launch lock.
- [ ] Qualify interrupted-wake recovery against live runtime lifecycle evidence;
owner attestation is explicit but is not independent proof of termination.
- [ ] Qualify the updated source as a clean commit before self-host activation;
- [x] Qualify the updated source as a clean commit before self-host activation;
older artifact receipts predate these changes. No fleet or timer has started.
Review verification (2026-09-30): full regression suite through isolated
@@ -961,7 +1071,7 @@ COMBATRIG's proposed hierarchy as the default.
multi-domain coordination/resume scenario with a fixed provider budget.
- [ ] Install and reverse the user-systemd scheduler, verifying one real
dispatch and its receipts.
- [ ] Install an accepted TORCH version in user-local versioned state and use
- [x] Install an accepted TORCH version in user-local versioned state and use
its stable launcher to manage this source checkout.
- [ ] Resolve COMBATRIG's 56 ownership/exclusion blockers, then separately
authorize an import/cutover trial. Do not mutate COMBATRIG beforehand.
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "torch-agent-fleet",
"version": "0.1.0-alpha.1",
"version": "0.1.0-alpha.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "torch-agent-fleet",
"version": "0.1.0-alpha.1",
"version": "0.1.0-alpha.2",
"bundleDependencies": [
"@modelcontextprotocol/server",
"typebox",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "torch-agent-fleet",
"version": "0.1.0-alpha.1",
"version": "0.1.0-alpha.2",
"type": "module",
"description": "TORCH — a portable, provider-independent AI development fleet for Git repositories",
"main": "src/cli.mjs",
@@ -0,0 +1,90 @@
# TORCH conversation-to-fleet handoff
## Installed domains
The installed organization is appropriately scoped to this repository: one
Session Manager and six specialists. A current read-only ownership query over
129 tracked files under `src`, `bin`, `site`, `schemas`, `scripts` and `test`
found zero unowned files and zero duplicate primary owners. This claim does not
cover every historical report or future new directory.
| Domain | Responsibility | Effective Codex model |
| --- | --- | --- |
| Session Manager | Routing, ownership, priority and fleet health | GPT-6.1 Sol high |
| Project Kernel | Bootstrap, identity, canonical instructions and organization | GPT-5.6 Terra high |
| Provider Runtime | Harnesses, MCP, lifecycle, schedules and telemetry | GPT-5.6 Terra high |
| Work and Integration | Backlog, checks, resources, landing and recovery | GPT-5.6 Terra high |
| Owner Console | Dashboard, artifacts, feedback and observability | GPT-6 Luna high |
| Release and Self-host | CLI, package, candidates, upgrades and removal | GPT-6 Luna high |
| Independent QA | Scenario integrity and real qualification | GPT-5.6 Terra high |
The six-role grouping was a reviewed consolidation of repository evidence,
not a copy of COMBATRIG's specialists and not proof of a fully autonomous AI
Architect first-run. Proposed extra domain leads are inactive. Headcount alone
does not justify adding managers. Significant pipeline work may justify different
model effort or a new domain later, through the existing review path.
## Authoritative backlog
Owner-request intake created 34 proposed, unassigned items in the existing
Session Manager worktree backlog. There are 33 current follow-ups plus the
earlier narrower `automatic-scheduler` request, retained for manager triage
against the newer `persistent-operations` requirement rather than silently
deleted. All have acceptance criteria, affected domains and observed commit
binding; dependent slices reference existing task IDs. No assignment, provider
start, self-claim enabling or host service installation occurred.
Run `torch backlog list --json` from any registered checkout. The canonical
backlog service resolves the manager's tracked ledger; do not create a second
copy in the source checkout. Task IDs below are prefixed `TASK-conversation-`.
| Group | Task suffixes |
| --- | --- |
| First work / readiness | `first-work-intake`, `development-activation`, `selfhost-development-trial` |
| Persistent operations | `persistent-operations`, `automatic-scheduler`, `event-driven-wakes`, `queue-watchdog`, `nightly-main-tests`, `usage-governor`, `idle-worktree-refresh`, `queue-planning`, `project-services` |
| Provider reliability | `runtime-diagnostics`, `startup-preflight`, `mcp-isolation`, `update-startpaths`, `mixed-provider-qualification` |
| Pipelines | `pipeline-definitions`, `pipeline-provenance`, `pipeline-flow`, `pipeline-stalls`, `pipeline-console`, `pipeline-metrics`, `pipeline-pilot` |
| Live qualification | `hierarchy-pilot`, `scheduler-qualification`, `browser-portability`, `landing-closure`, `closure-revert-review`, `delivery-qualification` |
| Owner/product/release | `owner-digest`, `console-workflow`, `documentation-current`, `release-qualification` |
## What is not yet automatic
Setup and retained-state restore have been qualified; installed alpha.2 is
healthy. All agents remain offline. The current manager schedule declares a
15-minute interval, but no TORCH-owned systemd units are installed or active.
Read-only host timer enumeration confirmed no TORCH timer; unrelated Archive
timers were untouched. The owner's latest request is that init/install provision
these integrations automatically. That is now an explicit target in specification
section 22 and the backlog, not an already delivered feature.
The shared common prompt still authorizes only an installation smoke test and
the project self-claim policy is disabled. Starting agents under it does not
authorize development. The manager should read and triage proposed work, recommend
a first bounded slice and budget, and obtain the development/startup approval
before delegation. New installs should offer reviewed TODO import or ask the
owner what they want first; repeated intake must deduplicate rather than queue
every historical checkbox.
## Suggested first implementation sequence
1. First-work intake and persistent operations planning/provisioning: make
the product's installation genuinely complete while stopped until ready.
2. Runtime diagnostics and exact launch preflight: make startup failures legible.
3. Separately approved bounded self-host development, landing/closure and
scheduler qualification, followed by persistent event/watchdog/nightly work.
4. Pipeline definitions, immutable provenance, checked transitions and Console.
5. Finish mixed-provider, organization-growth and release qualification.
There is no authorization here to promote the rewrite to default `main`, deploy
the public website, send notifications, alter COMBATRIG, spend on asset generation
or install active recurring AI wakes. Those boundaries remain in the task criteria.
## Validation
Installed `torch backlog list` sees all 34 items. Acceptance criteria and domains
are populated; every dependency exists and the dependency graph is acyclic.
Installed `torch backlog health` reports healthy with no anomalous assignments.
Its bounded historical activity coverage remains incomplete, correctly labelled
unknown rather than proof of inactivity. Existing backlog/scheduling regression
suite: 23/23 PASS. All seven identities remain offline. These are backlog/spec
changes, not implementation of the newly requested onboarding or automation.
@@ -0,0 +1,238 @@
# First TORCH-building-TORCH development pilot
## Owner authorization and live monitor
The owner requested a staged self-development fleet, with the outer assistant
as arbiter through Session Manager, then a quality release/update and a later
Claude Code/Pi substitution test. COMMON.md records the bounded first slice:
`TASK-conversation-runtime-diagnostics`. Other development work, remote pushes,
landing, public release, deployment, default-main promotion and provider migration
are not authorized by this pilot.
Monitor: **http://127.0.0.1:4174/console**. The snapshot is installed mode for
project `3dc11932-6e3c-42aa-9a8a-ca7b8f818b54`, not demo state. The original
Console process died during an outer-daemon restart. It was restored as the
loopback-only transient user service
`torch-3dc11932-6e3c-42aa-9a8a-ca7b8f818b54-console-pilot.service`, outside the
assistant process lifetime. This is not yet a reboot-persistent installed
Console integration; automatic service provisioning remains backlog work.
## Real agent evidence
- Session Manager resumed the same Sol runtime and assigned the real task to
Provider Runtime with revision-checked proposed → ready → assigned transitions.
- Provider Runtime started as the configured Terra model, retained runtime
session `01a0f3e1-9106-72c3-b8b2-2f1cc5322ccc`, queried ownership and requested
QA consent before editing tests. It committed production changes at
`c362ccd5cc8fff94c59d4a0c8f178628dc5e7596` on its own branch. That is not landed
or accepted release evidence.
- QA ran real Terra coordination turns and gave exact additive-test consent for
`test/fleet/lifecycle.test.mjs` and `docs/TEST_INTEGRITY.md`, retaining existing
assertions and requiring independent exact-candidate review.
- A daemon restart interrupted implementation. The arbiter checked owned live
Codex process absence, preserved dirty code/tests/generated screenshots and
resumed the same assignment via a transient `runtime-pilot-turn` user service.
No unrelated process was killed or user work reverted.
Provider-reported focused checks passed, but its generic full-suite failures and
final regression evidence still require exact-source qualification. Do not infer
completion from a commit, active process or green controller receipt. Generated
test screenshots remain agent work and must not be blindly committed as changed
expectations. First launch presence lag and assigned-versus-working task state
need review; startup badges are not independent process-liveness proof.
## Machine scheduler: qualified setup, guarded AI execution
The owner-approved hourly check-in policy retains a maximum of 12 automatic
invocations per UTC day in subscription invocation-count mode, not a USD cap.
The project-owned persistent systemd timer was explicitly installed for the
pilot. This manual qualification does not implement automatic init/install yet.
Initial live install exposed invalid `WorkingDirectory="/absolute/path"` output.
The actual parser rejected it, while file-based status said installed and the
timer was enabled but inactive. Minimal source repair `d636cae` emits an absolute
scalar path with C escaping and literal specifier handling. A new native-parser
scenario includes spaces, percent and quote characters. Fourteen scheduling tests
and all 39 source acceptance groups PASS; no existing test was weakened.
Reconciliation used the tested source CLI and preserved owned-file hashes. The
timer is active and its first dispatch produced a durable check-in and wake
receipt. Installed stable tool remains alpha.2; the repaired scheduler currently
executes the source CLI, not a newly packaged stable release. A later qualified
tool update must incorporate the repair and reconcile the launcher.
The first automatic manager invocation lasted exactly the 300-second executor
limit and was recorded succeeded/invoked. Independent model-turn completion was
not established. A native local child trapping SIGTERM reproduced
`status: 0`, `signal: null`, `error: ETIMEDOUT`; current startFleet ignores the
error when exit status is zero. This confirms a false-success boundary, not
independent proof of how that particular model turn ended. Historical receipts
were preserved, not rewritten.
Automatic AI wakes are therefore **disabled** until `TASK-pilot-executor-outcomes`
is fixed and qualified. The timer remains active for durable machine coordination;
the arbiter explicitly drives the bounded specialist turns. Do not claim the
fleet is ready for unattended autonomy.
## Backlog and next gates
The original 34 conversation follow-ups are preserved. Three observed pilot
issues were added through audited owner intake: starting presence, native unit
rendering/operational status and executor timeout/outcome semantics. The manager
backlog remains the authoritative queue, separate from this narrative report.
Recovery follow-up: the specialist produced regression commit `2f1ca15` but exact
TORCH check planning was blocked by five tracked report images generated by the
dashboard gate. The owner/arbiter gave narrow reversible archive-and-restore
directions for proven check-owned outputs, not permission to rewrite expectations.
`TASK-pilot-generated-check-artifacts` records the durable fix. The explicitly
requested post-quality-release whole-fleet provider migration now has its own
`TASK-provider-handover`, dependent on release qualification. Total intake is
39 items (34 original follow-ups plus five later pilot/handover items); one real
implementation assignment does not imply the rest are dispatched.
1. Finish diagnostics regression evidence and independent QA review.
2. Fix executor outcome/launch-presence guards and qualify one real bounded wake.
3. Complete reviewed automatic init/install onboarding and persistent operations.
4. Expand the fleet's scope only after a successful bounded work/verification/
landing/resume cycle; never directly push competing specialist branches.
5. Build/accept/update a quality artifact with current receipts, then separately
test Claude/Pi handover of the same durable identities, tasks, messages and
checkpoints. No model/provider swap occurred in this pilot.
Receipts are under `/tmp/torch-pilot-*`, including repaired full-source acceptance,
native parser tests, scheduler installation/reconciliation, durable wake/run
state and owner-request messages. The live dashboard and actual branch state
take precedence over historical progress descriptions in this report.
## Continued pilot and owner UX feedback
The owner approved continuing the controlled pilot and is watching the Console.
Independent QA reviewed candidate `ae18a98e2911aa515d0484518013061b05ff6adf`:
the lifecycle scenario independently PASSed 7/7, with no assertion relaxation.
QA accepted code/scenario content, **not integration qualification**. Required
dashboard receipt remains incomplete and canonical convergence remains required.
QA's durable report is message `8275d64a-7b28-49ee-a379-2c6d0bdcacb3`.
Two additional owner-intake proposals bring the backlog to 41:
- `TASK-owner-agent-chat`: threaded durable owner conversations and reviewed
wake-on-message after executor/presence qualification. Current agent message
recipient validation does not permit the owner as a recipient; owner replies
need a distinct authorized API, not an invented specialist identity.
- `TASK-console-ux-audit`: the owner rejects excessive scrolling and a generic
all-in-one-page dashboard. Session Manager has an explicit bounded assignment
request for existing Owner Console. Require actual computer-use navigation,
inspected screenshots of every current area, desktop/mobile and interaction
coverage, and a focused multi-screen proposal. Live state is read-only; demo
may exercise mutations. Missing browser tools are a blocker, not permission
to claim a source-only audit completed the request.
Canonical COMMON now permits this audit in parallel with diagnostics QA, without
authorizing UI implementation, unrelated dispatch, automatic wakes or release.
The arbiter launches Owner Console only after actual manager assignment; a
request in an inbox is not itself assignment evidence.
## Attention-panel triage and audit recovery
Session Manager assigned `TASK-console-ux-audit` to Owner Console at revision 3.
The first audit turn **did not perform browser coverage**: installed `torch brief`
failed with `ERR_SQLITE_ERROR` / read-only database. The identical installed brief
passes from the host. The arbiter resumed the same session with directions to
request narrowly scoped escalation for that exact command, not change permissions
or skip the guard. `TASK-pilot-brief-sandbox` captures durable qualification.
Owner additionally requests contextual quick actions in Needs your attention.
`TASK-console-attention-actions` requires meaningful per-agent/branch findings,
deduplicated messages and owner-only reviewed approve/reject actions. Total
owner intake is now 43. It does not authorize warning dismissal, blanket message
acknowledgement, automatic merging or remote publication.
Observed worktree warnings: manager backlog updates are dirty, and manager and
Provider Runtime retain unique commits. These are preserved task state and
unlanded work, not permission to remove worktrees or discard commits. The manager
has a narrowly authorized local backlog checkpoint/convergence request and must
review its own inbox. Provider code still requires integration gates.
Recovery is `ONE-DISK` for current rewrite HEAD: origin exists, but local
remote-tracking references do not contain that commit. This is not proof of a
live remote query. Off-machine synchronization requires an explicit owner
publication/backup decision; no remote push or default-main promotion occurred.
## Bounded coordination and reliability follow-through
The owner clarified that ordinary peer coordination should not require human
relay. Live COMMON and Session Manager instructions now require own-inbox review,
named-approver decisions, durable unresolved waits and direct responsible-peer
follow-up. Spending, publication, releases, scope/ownership changes, destructive
recovery and owner-addressed approvals remain reserved. There are 44 backlog
items; `TASK-bounded-routine-coordination` carries this policy into fresh installs.
Project Kernel committed candidate `d3a679849b0f5e55c2114223a2e56977c318391e`.
The arbiter independently ran its new routine-coordination test: **2/2 PASS**.
This covers generated instruction surfaces, acknowledgement not completing work,
and named-approver enforcement. It does not independently prove paused runtime
execution or full integration qualification. QA has a review request for that
coverage gap. Kernel reports test/check/lint evidence, but its dashboard gate is
blocked: root Playwright is 1.58.2, Kernel's installed dependency is 1.63.0, and
the latter expects absent `chromium_headless_shell-1243`. QA and manager were
asked to resolve reproducible setup, not waive assertions or use an unverified
browser substitution.
Session Manager explicitly blocked the earlier runtime diagnostics task while
preserving its accepted candidate and incomplete dashboard receipt. It then
assigned `TASK-pilot-executor-outcomes` to Provider Runtime and
`TASK-pilot-generated-check-artifacts` to Work and Integration, one active item
per specialist. Named QA additive-test/output-plumbing consent and Release CLI
consent were requested through the control plane. The arbiter started their
review turns and both assigned implementation turns using separate owned
transient user services. A running service proves an active launch handle, not
task completion or successful native terminal output.
All three named peer consents subsequently reached **approved revision 2**:
QA `e198e23b-772f-42d5-89df-5c4891df904f` and
`649f7e47-8b94-4b02-a1e6-962fde3e24a7`, and Release
`200dcdba-9337-4e6f-a218-d02c7bda458a`. The responsible peers sent their bounded
decisions directly to specialists and manager. Actual native Codex processes
were verified in the Provider Runtime and Work and Integration worktrees;
the Console subsequently showed both as working. These are successful peer
coordination outcomes, not completed implementation or independent acceptance.
Owner Console is continuing its actual browser audit through a bounded temporary
diagnostic launcher. The launcher captures outcome metadata only, checks terminal
turn evidence and refuses false success. Its larger output buffer is diagnostic
recovery, **not an installed engine fix**. The permanent executor task must handle
timeouts, signals, errors, output overflow and uncertain captured identities.
Automatic wakes remain paused; no remote push, release, installation update or
default-main promotion has occurred.
## Independent follow-up: completion evidence and review gaps
The first temporary Console probe completed with status 0, no executor error or
signal, 64 valid protocol records and a final `turn.completed` event. It captured
141,317 stdout bytes. This proves that diagnostic turn completed, **not that its
audit task completed**; the audit addendum still records missing computer-use
coverage. A fresh arbiter browser connection and fresh tab subsequently produced
an actually viewed single-viewport Overview capture in about four seconds. The
same Console identity was resumed with that recovery evidence, without duplicate
launch or a claim that the earlier interruption was caused by output overflow.
QA independently confirmed Kernel's focused 2/2 pass, but rejected full policy
acceptance because paused execution was only text-matched and manual test reports
were not durable TORCH check receipts. Kernel was resumed for an additive real
paused-dispatch boundary scenario. Both tracked lockfiles pin Playwright 1.58.2;
Kernel's 1.63.0 installation is an environment mismatch, not an intended upgrade.
Work and Integration created candidate
`f46c713cc9e90697d02e3e29222b3eeb7cd71d99`. Arbiter independently ran its two new
artifact scenarios: **2/2 PASS**, covering sequential external hashed outputs
and an exit-zero source mutation remaining incomplete. Full dashboard,
convergence and independent acceptance remain outstanding.
An early review of Provider Runtime's uncommitted executor draft found remaining
workflow gaps: status-zero success without terminal evidence, reducing scheduled
output capacity rather than safely handling screenshot-rich turns, discarding
initial runtime identity on large output, and insufficient public-boundary tests.
Specific evidence was routed to Provider Runtime, QA and Session Manager. This
is in-progress review feedback, not an accepted fix. The manager was resumed to
follow direct-report waits and task/evidence state; automatic wakes remain paused.
@@ -0,0 +1,59 @@
# Guided setup and reinstall verification
## Changes
- `torch brief` and normal installed-project CLI commands resolve registered
worktrees to the canonical project. The resolver checks project and installation
IDs, XDG state binding, Git common directory, worktree membership and branch.
Current canonical instructions win over an old worktree copy.
- `torch setup --dry-run`, then `--yes`, checkpoints owned configuration,
provisions worktrees and checkpoints registration. Existing staged work is
rejected; unrelated files are not staged. Install can opt in with `--setup`.
- `torch install --restore` reattaches the retained state from normal uninstall.
It does not overwrite profiles, erase history, recreate timers or start agents.
- The self-host smoke brief distinguishes manager backlog inspection from
specialist next-task lookup and explicitly requires current briefs.
## Evidence before installation
All 39 source acceptance groups, lint and syntax: PASS.
Receipt: `/tmp/torch-alpha2-source-acceptance.json`.
New scenarios: guided setup, canonical worktree briefs, safe detach/restore.
The actual Owner Console worktree returned its current brief successfully
through the patched source CLI, including its preserved offline runtime ID.
## Installation trial
Accepted alpha.2 source: `c11754ab18fa690355ead3f6f87b3accb2975153`.
Candidate digest: `d4b6ba38a51cc1804047b175c963806850f017a92d88863d187043314414dd90`.
All 39 acceptance groups passed again from the copied candidate. Active version
is `0.1.0-alpha.2`; rollback retains alpha.1.
Normal uninstall: PASS. Retained-state restore: PASS. All seven actual agent
worktrees returned briefs through `/home/user/.local/bin/torch`: PASS. Their
briefs include the updated canonical smoke instructions despite older worktree
copies. Model configuration hash, project/installation IDs, offline states,
saved Codex runtime IDs and all seven branch tips were unchanged across
uninstall/restore. No provider was launched.
The restored project's `torch setup --yes --json` was a no-op: no commits,
no mutations, no sessions started. Final doctor reports healthy. Modified owned
configuration and unique manager history remain legitimate safety warnings,
not authorization to purge. Uninstall refreshed the manager resume brief;
that generated file was separately checkpointed on its existing branch, without
rewriting prior history or landing anything.
Receipts:
- `/tmp/torch-alpha2-candidate-build.json`
- `/tmp/torch-alpha2-uninstall-plan.json`
- `/tmp/torch-alpha2-uninstall-result.json`
- `/tmp/torch-alpha2-restore-result.json`
- `/tmp/torch-alpha2-reinstall-verification.json`
- `/tmp/torch-alpha2-real-setup-result.json`
- `/tmp/torch-alpha2-real-doctor.json`
This tests retained-state reinstall, not destructive purge or a fresh installation
with discarded configuration. New-install setup is covered by isolated real-Git
regression tests. Provider-authentication and new agent launches were deliberately
not repeated. Host timers remain uninstalled.
@@ -0,0 +1,145 @@
# Live Console arbiter usability audit
## Evidence and scope
Owner requested direct inspection of `http://127.0.0.1:4174/console` and a report
to Session Manager. Inspected the real installed workspace in the connected Brave
browser using interactive navigation, DOM observations and actually viewed
viewport screenshots. No live task, approval, profile, release or message was
mutated through the browser. Expanded the request composer and one incomplete
check receipt only. Screenshots were viewed in this audit conversation; no new
artifact catalog or saved screenshot files are claimed.
Visited all ten navigation entries: Overview, Briefing, Flow watch, Work,
Progress, Fleet, Conversations, Organization, Evidence and Release gates.
Temporary narrow viewport was reset afterward. Desktop DOM viewport was
1253×685. Requested mobile override 390×844 produced reported CSS viewport
433×938 in this browser; responsive measurements below use the reported values.
No full keyboard audit, draft/refresh experiment, approval submission, empty/error
simulation or hidden Operations panel coverage is claimed. Those remain the
assigned UI agent's coverage requirements.
## Prioritized findings
### P1: one document makes monitoring impractical
Desktop document height measured 50,288 pixels. Work occupied 36,662 pixels,
Conversations 5,723 and Organization 2,931 at the observation point. Navigation
changes URL fragments and scroll position rather than opening focused views.
The masthead/project/freshness controls scroll away on lower sections. Current
nav styling exists, but every navigation link lacked `aria-current`.
Use addressable separate screens with persistent project context. Keep Overview
to a concise pulse, real decisions, blockers and recent outcomes. Route detail
links to exact task, agent, check or decision rather than a broad section.
### P1: work-card density dominates the page
There were 43 active tasks, including 41 Queue cards. Narrow desktop kanban
columns wrap IDs and titles heavily and show full long descriptions. Filtering,
saved-view editing and task creation sit above the actual work. At narrow size,
the filter block alone measured approximately 572 CSS pixels, followed by a
horizontally navigated kanban.
Use compact task summaries with a detail drawer/page. Separate proposed backlog
from active work by default; retain one authoritative task system. Put secondary
filters/saved-view editing behind an intentional control. Mobile should offer a
usable list or selected-column view, not require navigating every column.
### P1: attention is opaque and duplicates the same condition
Actual Overview repeated MESSAGE_BACKLOG plus the unacknowledged message count,
and three WORKTREE_PROBLEM entries all said only “Doctor reported a project
condition to review.” Unique commits and manager backlog edits are not equivalent
to a failed merge or missing tree. The Healthy badge can imply more operational
readiness than these conditions justify; the existing doctor threshold may be
valid, but the UI label should describe its narrower meaning.
Implement `TASK-console-attention-actions`: group and deduplicate actual entities,
name identity/branch/reason, distinguish safety gates from routine agent progress.
Offer owner Approve/Reject only for an actual pending owner-addressed approval,
using current revision/evidence preview-confirm checks. Offer exact inspect,
message/review or supported recovery actions otherwise. No blanket dismiss,
peer-message acknowledgement, merge, deletion or publication shortcut.
### P1: conversations is an internal transcript, not owner chat
Two-column entries expose entire long coordination instructions. There is no
agent-thread picker, compact subject/task grouping or focused reply experience.
The expanded installed request composer displayed “Install a reviewed Fleet
before sending owner requests” while identity options were populated and Preview
request was present. This contradicts the installed workspace state. Existing
request composition is not a native owner reply channel or automatic wake.
Implement `TASK-owner-agent-chat` with truthful per-agent threading, delivery and
reply states. Keep engineering message detail expandable; show concise relevant
summaries first. Fix stale placeholder status from actual capability state.
### P2: fleet, ownership and organization repeat technical metadata
Fleet repeats runtime/model/profile text and mixes implementation paths with
session monitoring. Organization cards repeat peer links and large owned-path
lists; the QA role shows an extensive historical report-file inventory. These
are useful audit details but poor default monitoring content.
Use a compact agent table/list showing work, state, last evidence, blocker and
chat/open actions. Put ownership paths and authority into agent detail. Use an
actual hierarchy/relationships view for Organization with a details inspector.
Do not replace observed presence with inferred process liveness.
### P2: briefing and progress do not provide a quick owner outcome
Briefing was unpublished and instructed the owner to run digest build/publish CLI
commands. Progress showed feature/milestone group totals but did not provide an
obvious exact-task drilldown. Preserve its good distinction between task progress
and verification/release readiness.
Provide permission-aware local generate/review/publish flow when supported and
link progress groups to filtered work. Do not send notifications or publish a
release as a side effect of preparing a local briefing.
### P2: evidence is honest but recovery navigation is weak
Expanded test-dashboard receipt correctly showed incomplete,
worktree-changed-during-check, exact SHA and missing frozen/condition evidence.
This is valuable and must remain strict. Artifacts are not connected yet;
integration/delivery records are empty and correctly avoid implying deployment.
Flow watch still said timer installation not verified despite the earlier
host-qualified timer; review how operational evidence reaches this snapshot,
rather than merely removing the warning.
Add links from an incomplete check to its task, author, candidate and blocking
condition. Show the reviewed next step without turning “retry” into an automatic
repeat of uncertain effects. Place receipts and advanced operational detail on
the relevant screen, not below every unrelated workflow.
## Proposed information architecture
- Overview: concise project outcome, decisions, blockers, recent events.
- Work: active work; compact proposed backlog; filters and exact task detail.
- Agents: state/work/waits, per-agent chat and profile/ownership detail.
- Pipelines: conditional project-defined flows, deliverables and stage history.
- Evidence: checks/artifacts with exact task/commit links and review actions.
- Releases: integration, delivery and separately authorized recovery.
- Organization / Settings: hierarchy, ownership, operations and configuration.
Briefing may be accessible from Overview; advanced operational panels should have
their own destination. Retain dark mode and original TORCH mark. Avoid filling
every view with duplicate cards or decorative labels.
## Implementation acceptance recommendations
1. A navigation action displays only its focused workspace, preserves project
identity/freshness, and supports addressable reload/back/forward behavior.
2. Forty-plus proposed tasks do not make Overview or agent conversations taller;
compact cards and bounded/paginated detail preserve all underlying records.
3. Attention is entity-specific and deduplicated, with authority-aware actions
and unchanged stale-preview/revision/evidence safety checks.
4. Installed request status derives from current capability, not leftover loading
copy. Per-agent threads remain readable after reload and provider changes.
5. Narrow/mobile monitoring reaches work and actions without a full-screen wall
of filters; current navigation is accessible via focus and `aria-current`.
6. Independent browser scenarios verify navigation, refresh/drafts, mobile,
pending approvals, wrong approver, incomplete checks and failed launches.
This report is audit evidence and a proposal, not implementation qualification.
+19 -4
View File
@@ -24,6 +24,8 @@ import { diagnoseProject } from './kernel/doctor.mjs';
import { loadProjectConfig, validateProjectConfig } from './kernel/config.mjs';
import { asErrorRecord, TorchError } from './kernel/errors.mjs';
import { inspectRepository } from './kernel/git.mjs';
import { resolveInstalledProjectRoot } from './kernel/project-root.mjs';
import { setupProject, restoreProject } from './kernel/setup.mjs';
import { inspectSpecifications } from './kernel/specifications.mjs';
import { installProject, planInstall, uninstallProject } from './kernel/install.mjs';
import { IntegrationService } from './integration/service.mjs';
@@ -72,6 +74,8 @@ Usage:
torch domains [--repo <path>] [--spec <path>] [--output <path>] [--json]
torch install --proposal <path> [--runtime <adapter,adapter>] [--default-runtime <adapter>] [--update-runtimes] [--dry-run] [--yes] [--json]
torch worktrees [--parent <path>] [--dry-run] [--yes] [--json]
torch install --restore [--dry-run] [--yes] [--json]
torch setup [--parent <path>] [--dry-run] [--yes] [--json]
torch up [--fresh] [--only <id,id>] [--dry-run] [--yes] [--json]
torch down [--dry-run] [--yes] [--json]
torch capture [--json]
@@ -414,7 +418,7 @@ export const CANDIDATE_ACCEPTANCE_EVIDENCE = Object.freeze({
'forge-migration': ['SCN-forge-migration'],
'delivery-lifecycle': ['SCN-delivery-lifecycle', 'SCN-delivery-attempts', 'SCN-delivery-retry-boundaries', 'SCN-delivery-succeeded-recovery',
'SCN-owner-digest', 'SCN-owner-digest-schedule', 'SCN-owner-digest-receipts'],
'review-install-roster': ['SCN-cli-domain-review', 'SCN-cli-install-provider-default', 'SCN-install-provider-inheritance'],
'review-install-roster': ['SCN-cli-domain-review', 'SCN-cli-install-provider-default', 'SCN-install-provider-inheritance', 'SCN-guided-setup'],
'branches-worktrees': ['SCN-worktree-bootstrap'],
'runtime-identities': ['SCN-mixed-runtime'],
'runtime-profiles': ['SCN-runtime-profiles', 'SCN-runtime-cost-ceiling', 'SCN-runtime-profile-cli'],
@@ -471,7 +475,7 @@ export const CANDIDATE_ACCEPTANCE_EVIDENCE = Object.freeze({
'capture-stop-resume': [
'SCN-fleet-fresh-resume', 'SCN-hierarchy-aware-start-stop', 'SCN-hierarchy-startup-cycle',
],
'detach-uninstall': ['SCN-install-doctor-purge'],
'detach-uninstall': ['SCN-install-doctor-purge', 'SCN-install-restore', 'SCN-worktree-canonical-brief'],
'combatrig-compatibility': ['SCN-combatrig-import', 'SCN-cli-combatrig-import'],
'product-surface': ['SCN-product-site', 'SCN-dashboard-demo', 'SCN-console-readonly', 'SCN-console-lifecycle-blockers',
'SCN-console-owner-digest', 'SCN-demo-owner-digest', 'SCN-console-check-evidence', 'SCN-console-task-activity', 'SCN-console-operation-outcomes', 'SCN-console-live-refresh'],
@@ -796,7 +800,9 @@ export async function runCli(argv = process.argv.slice(2), {
}
const designCommand = ['init', 'analyze', 'domains', 'design', 'bootstrap'].includes(command);
const repositoryRoot = designCommand ? resolve(cwd, optionValue(argv, '--repo') ?? '.') : cwd;
const repository = inspectRepository(repositoryRoot);
const inspectedRepository = inspectRepository(repositoryRoot);
const repository = designCommand ? inspectedRepository
: inspectRepository(resolveInstalledProjectRoot(inspectedRepository.root, env));
if (command === 'profile') {
const operation = argv[1] ?? 'show';
const areaId = optionValue(argv, '--area');
@@ -997,6 +1003,11 @@ export async function runCli(argv = process.argv.slice(2), {
return 0;
}
if (command === 'install') {
if (argv.includes('--restore')) {
const result = restoreProject({ repository, env, dryRun: argv.includes('--dry-run'), authorized: argv.includes('--yes') });
print(result, { json });
return 0;
}
const proposalPath = optionValue(argv, '--proposal');
const runtimeOption = optionValue(argv, '--runtime');
const defaultRuntime = optionValue(argv, '--default-runtime');
@@ -1038,7 +1049,11 @@ export async function runCli(argv = process.argv.slice(2), {
}
persistProfileConfig(repository.root, config);
}
print(installed, { json });
print(argv.includes('--setup') ? { ...installed, setup: setupProject({ repository: inspectRepository(repository.root), env, authorized: true, parentOverride: optionValue(argv, '--parent') }) } : installed, { json });
return 0;
}
if (command === 'setup') {
print(setupProject({ repository, env, authorized: argv.includes('--yes'), dryRun: argv.includes('--dry-run'), parentOverride: optionValue(argv, '--parent') }), { json });
return 0;
}
if (command === 'doctor') {
+38
View File
@@ -0,0 +1,38 @@
import { execFileSync } from 'node:child_process';
import { existsSync, readFileSync, realpathSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { projectStatePath } from './paths.mjs';
import { TorchError } from './errors.mjs';
const read = path => JSON.parse(readFileSync(path, 'utf8'));
const git = (root, args) => execFileSync('git', ['-C', root, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
// A worktree's copied configuration is not authoritative. Only registered,
// same-installation worktrees may resolve to the current canonical definition.
export function resolveInstalledProjectRoot(root, env = process.env) {
root = realpathSync(root);
const path = join(root, '.torch', 'install-manifest.json');
if (!existsSync(path)) return root;
const manifest = read(path);
const stateRoot = projectStatePath(manifest.projectId, env);
const local = manifest.external?.find(entry => entry.type === 'local-state');
if (!local || resolve(local.path) !== resolve(stateRoot)) {
throw new TorchError('Installation state path does not match this project', { code: 'LOCAL_STATE_PATH_MISMATCH' });
}
const metadata = read(join(stateRoot, 'project.json'));
if (metadata.projectId !== manifest.projectId) {
throw new TorchError('Installation metadata belongs to another project', { code: 'LOCAL_STATE_METADATA_MISMATCH' });
}
const canonical = realpathSync(metadata.root);
if (canonical === root) return root;
const current = read(join(canonical, '.torch', 'install-manifest.json'));
const registered = current.external?.find(entry => entry.type === 'worktree' && existsSync(entry.path) && realpathSync(entry.path) === root);
const common = directory => realpathSync(resolve(directory, git(directory, ['rev-parse', '--git-common-dir'])));
const members = git(canonical, ['worktree', 'list', '--porcelain']).split('\n').filter(line => line.startsWith('worktree ')).map(line => realpathSync(line.slice(9)));
if (current.projectId !== manifest.projectId || current.installationId !== manifest.installationId
|| !registered || common(root) !== common(canonical) || !members.includes(root)
|| git(root, ['branch', '--show-current']) !== registered.branch) {
throw new TorchError('This checkout is not a registered worktree of the installation', { code: 'UNREGISTERED_PROJECT_WORKTREE' });
}
return canonical;
}
+55
View File
@@ -0,0 +1,55 @@
import { execFileSync } from 'node:child_process';
import { readFileSync, renameSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { inspectRepository } from './git.mjs';
import { readInstallManifest } from './install.mjs';
import { projectStatePath } from './paths.mjs';
import { resolveInstalledProjectRoot } from './project-root.mjs';
import { createWorktrees, planWorktrees } from './worktrees.mjs';
import { TorchError } from './errors.mjs';
const git = (root, args) => execFileSync('git', ['-C', root, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
export function setupProject({ repository, env = process.env, authorized = false, dryRun = false, parentOverride }) {
const root = resolveInstalledProjectRoot(repository.root, env);
repository = inspectRepository(root);
const manifest = readInstallManifest(root);
const owned = [...new Set([...manifest.created.map(record => record.path), '.torch/install-manifest.json'])];
const changed = owned.filter(path => git(root, ['status', '--porcelain=v1', '--', path]));
const staged = git(root, ['diff', '--cached', '--name-only']);
if (staged) throw new TorchError('Setup requires an empty staging area; preserve and finish your existing staged work first', { code: 'SETUP_STAGED_WORK', details: staged });
const unrelated = repository.dirtyEntries.filter(entry => !owned.includes(entry.slice(3)));
const worktrees = planWorktrees({ repository: { ...repository, dirtyEntries: unrelated }, parentOverride });
const plan = { action: 'setup', projectId: manifest.projectId, checkpointPaths: changed, worktrees, canProceed: worktrees.canProceed, sessionsStarted: false, mutationPerformed: false };
if (dryRun) return plan;
if (!authorized) throw new TorchError('Setup commits TORCH-owned configuration and provisions worktrees; review --dry-run then use --yes', { code: 'APPROVAL_REQUIRED' });
if (!plan.canProceed) throw new TorchError('Setup has blockers', { code: 'SETUP_BLOCKED', details: worktrees.conflicts });
const checkpoint = (paths, message) => {
const pending = paths.filter(path => git(root, ['status', '--porcelain=v1', '--', path]));
if (!pending.length) return null;
git(root, ['add', '--', ...pending]);
git(root, ['commit', '--only', '-m', message, '--', ...pending]);
return git(root, ['rev-parse', 'HEAD']);
};
const configurationCommit = checkpoint(changed, 'Checkpoint approved TORCH configuration');
const provisioned = createWorktrees({ repository: inspectRepository(root), parentOverride });
const registrationCommit = checkpoint(['.torch/install-manifest.json'], 'Checkpoint TORCH worktree registration');
return { ...plan, configurationCommit, registrationCommit, provisioned, mutationPerformed: Boolean(configurationCommit || registrationCommit || provisioned.mutationPerformed) };
}
export function restoreProject({ repository, env = process.env, authorized = false, dryRun = false }) {
const root = resolveInstalledProjectRoot(repository.root, env);
const manifest = readInstallManifest(root);
const path = join(projectStatePath(manifest.projectId, env), 'project.json');
const metadata = JSON.parse(readFileSync(path, 'utf8'));
const result = { action: 'restore-installation', projectId: manifest.projectId, installationId: manifest.installationId, wasDetached: Boolean(metadata.detachedAt), preserved: ['configuration', 'worktrees', 'branches', 'session history', 'provider profiles'], sessionsStarted: false, mutationPerformed: false };
if (dryRun) return result;
if (!authorized) throw new TorchError('Restoring a retained installation requires --yes', { code: 'APPROVAL_REQUIRED' });
if (metadata.detachedAt) {
const temporary = `${path}.restore-${process.pid}`;
writeFileSync(temporary, `${JSON.stringify({ ...metadata, detachedAt: null, attachedAt: new Date().toISOString() }, null, 2)}\n`, { flag: 'wx', mode: 0o600 });
renameSync(temporary, path);
result.mutationPerformed = true;
}
return result;
}
+13 -1
View File
@@ -15,6 +15,18 @@ function unitQuote(value) {
return `"${String(value).replaceAll('\\', '\\\\').replaceAll('"', '\\"')}"`;
}
// WorkingDirectory is a scalar path, not an ExecStart-style quoted word.
// C-escape special path bytes and escape systemd specifiers without adding quotes.
function unitPath(value) {
return [...String(value)].map(character => {
if (character === '%') return '%%';
if (character.charCodeAt(0) <= 0x20 || character === '\\' || character === '"') {
return `\\x${character.charCodeAt(0).toString(16).padStart(2, '0')}`;
}
return character;
}).join('');
}
function configPath(repositoryRoot) {
return join(repositoryRoot, '.torch', 'torch.yaml');
}
@@ -39,7 +51,7 @@ function render({ repositoryRoot, projectId, command, digest, env }) {
? `Environment=${unitQuote(`XDG_DATA_HOME=${resolve(env.XDG_DATA_HOME)}`)}\n` : '';
const service = [
'[Unit]', `Description=TORCH system schedules for ${projectId}`, '', '[Service]', 'Type=oneshot',
`WorkingDirectory=${unitQuote(repositoryRoot)}`, environment.trimEnd(),
`WorkingDirectory=${unitPath(repositoryRoot)}`, environment.trimEnd(),
`ExecStart=${args.map(unitQuote).join(' ')}`, '',
].filter((line) => line !== '').join('\n') + '\n';
const timer = [
+20 -1
View File
@@ -1,6 +1,6 @@
import assert from 'node:assert/strict';
import { execFileSync, spawnSync } from 'node:child_process';
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
import { existsSync, mkdtempSync, readFileSync, symlinkSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
@@ -16,6 +16,25 @@ import { loadProjectConfig, validateProjectConfig } from '../../src/kernel/confi
import { CheckService } from '../../src/checks/service.mjs';
import { IntegrationService } from '../../src/integration/service.mjs';
import { createWorktrees } from '../../src/kernel/worktrees.mjs';
test('SCN-systemd-native-unit: generated dispatcher is accepted by the real systemd parser', (t) => {
if (process.platform !== 'linux') return t.skip('Native systemd qualification is Linux-specific');
const context = fixture();
const alias = join(mkdtempSync(join(tmpdir(), 'torch-unit-path-')), 'project space % "quoted"');
symlinkSync(context.root, alias, 'dir');
const launcher = new ScheduleLauncherService({ repositoryRoot: alias, env: context.env, command: ['/usr/bin/true'] });
const plan = launcher.plan();
const service = plan.files.find(file => file.name.endsWith('.service'));
const directory = mkdtempSync(join(tmpdir(), 'torch-systemd-verify-'));
const path = join(directory, service.name);
writeFileSync(path, service.content);
assert.match(service.content, /WorkingDirectory=\//);
assert.ok(!service.content.includes('WorkingDirectory="'));
assert.ok(service.content.includes('project\\x20space\\x20%%\\x20\\x22quoted\\x22'));
const checked = spawnSync('systemd-analyze', ['--user', 'verify', path], { encoding: 'utf8' });
assert.equal(checked.error, undefined, checked.error?.message);
assert.equal(checked.status, 0, checked.stderr);
});
import { createRuntimeAdapterRegistry } from '../../src/adapters/registry.mjs';
import { planAreaUp } from '../../src/runtime/lifecycle.mjs';
import { observeProject } from '../../src/observability/snapshot.mjs';
+101
View File
@@ -0,0 +1,101 @@
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { mkdtempSync, readFileSync, writeFileSync, cpSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
import { proposeDomains } from '../../src/kernel/domains.mjs';
import { inspectRepository } from '../../src/kernel/git.mjs';
import { installProject, readInstallManifest } from '../../src/kernel/install.mjs';
import { resolveInstalledProjectRoot } from '../../src/kernel/project-root.mjs';
import { setupProject, restoreProject } from '../../src/kernel/setup.mjs';
import { openControlPlane } from '../../src/control-plane/service.mjs';
import { createFleetBrief, detachFleet, planFleetDetach } from '../../src/runtime/lifecycle.mjs';
const git = (root, args) => execFileSync('git', ['-C', root, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
function fixture() {
const root = mkdtempSync(join(tmpdir(), 'torch-setup-'));
const env = { ...process.env, XDG_DATA_HOME: join(root, 'external-state') };
git(root, ['init', '-b', 'main']);
git(root, ['config', 'user.name', 'Setup Test']);
git(root, ['config', 'user.email', '[email protected]']);
writeFileSync(join(root, '.gitignore'), 'external-state/\nworktrees/\n');
writeFileSync(join(root, 'app.js'), 'export const app = true;\n');
git(root, ['add', '.']);
git(root, ['commit', '-m', 'fixture']);
const repository = inspectRepository(root);
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
proposal.review = { status: 'approved', reviewedAt: '2026-09-30T00:00:00Z', reviewedBy: 'owner', notes: [] };
installProject({ repository, proposal, env });
return { root, env, parentOverride: join(root, 'worktrees') };
}
test('SCN-guided-setup: approved setup checkpoints owned files and provisions without agents', () => {
const f = fixture();
const before = git(f.root, ['rev-parse', 'HEAD']);
assert.equal(setupProject({ ...f, repository: inspectRepository(f.root), dryRun: true }).canProceed, true);
assert.equal(git(f.root, ['rev-parse', 'HEAD']), before);
assert.throws(() => setupProject({ ...f, repository: inspectRepository(f.root) }), { code: 'APPROVAL_REQUIRED' });
writeFileSync(join(f.root, 'app.js'), 'export const app = false;\n');
git(f.root, ['add', 'app.js']);
assert.throws(() => setupProject({ ...f, repository: inspectRepository(f.root), authorized: true }), { code: 'SETUP_STAGED_WORK' });
assert.equal(git(f.root, ['diff', '--cached', '--name-only']), 'app.js');
git(f.root, ['restore', '--staged', 'app.js']);
writeFileSync(join(f.root, 'app.js'), 'export const app = true;\n');
const result = setupProject({ ...f, repository: inspectRepository(f.root), authorized: true });
assert.equal(result.sessionsStarted, false);
assert.ok(result.configurationCommit);
assert.ok(result.registrationCommit);
assert.equal(git(f.root, ['status', '--porcelain']), '');
assert.ok(git(f.root, ['diff', '--name-only', before, 'HEAD']).split('\n').every(path => path.startsWith('.torch/')));
assert.ok(readInstallManifest(f.root).external.some(entry => entry.type === 'worktree'));
assert.equal(setupProject({ ...f, repository: inspectRepository(f.root), authorized: true }).mutationPerformed, false);
});
test('SCN-worktree-canonical-brief: current instructions win and unregistered or copied worktrees fail closed', () => {
const f = fixture();
setupProject({ ...f, repository: inspectRepository(f.root), authorized: true });
const entry = readInstallManifest(f.root).external.find(item => item.type === 'worktree');
const marker = 'Current canonical instructions, not the old worktree copy.';
writeFileSync(join(f.root, '.torch/prompts/COMMON.md'), marker);
const canonical = resolveInstalledProjectRoot(entry.path, f.env);
assert.equal(canonical, f.root);
const control = openControlPlane({ repositoryRoot: canonical, env: f.env });
try {
const brief = createFleetBrief({ repositoryRoot: canonical, controlPlane: control, areaId: entry.area });
assert.ok(brief.areas[0].prompt.includes(marker));
} finally { control.close(); }
const stray = join(f.root, 'worktrees', 'stray');
git(f.root, ['worktree', 'add', '-b', 'stray', stray]);
assert.throws(() => resolveInstalledProjectRoot(stray, f.env), { code: 'UNREGISTERED_PROJECT_WORKTREE' });
const copied = mkdtempSync(join(tmpdir(), 'torch-copy-'));
cpSync(join(entry.path, '.torch'), join(copied, '.torch'), { recursive: true });
git(copied, ['init', '-b', entry.branch]);
assert.throws(() => resolveInstalledProjectRoot(copied, f.env), { code: 'UNREGISTERED_PROJECT_WORKTREE' });
const localManifest = JSON.parse(readFileSync(join(entry.path, '.torch/install-manifest.json')));
localManifest.installationId = 'stale-installation';
writeFileSync(join(entry.path, '.torch/install-manifest.json'), JSON.stringify(localManifest));
assert.throws(() => resolveInstalledProjectRoot(entry.path, f.env), { code: 'UNREGISTERED_PROJECT_WORKTREE' });
});
test('SCN-install-restore: detach and explicit restore preserve configuration and worktree history without starting sessions', () => {
const f = fixture();
setupProject({ ...f, repository: inspectRepository(f.root), authorized: true });
const manifest = readInstallManifest(f.root);
const metadataPath = join(manifest.external.find(entry => entry.type === 'local-state').path, 'project.json');
const config = readFileSync(join(f.root, '.torch/torch.yaml'), 'utf8');
const heads = manifest.external.filter(entry => entry.type === 'worktree').map(entry => git(entry.path, ['rev-parse', 'HEAD']));
const control = openControlPlane({ repositoryRoot: f.root, env: f.env });
try {
detachFleet({ plan: planFleetDetach({ repositoryRoot: f.root, controlPlane: control, adapters: {} }), controlPlane: control, stopRuntime: () => { throw new Error('Offline setup must not call a provider'); } });
} finally { control.close(); }
const before = readFileSync(metadataPath, 'utf8');
assert.equal(restoreProject({ repository: inspectRepository(f.root), env: f.env, dryRun: true }).wasDetached, true);
assert.equal(readFileSync(metadataPath, 'utf8'), before);
assert.throws(() => restoreProject({ repository: inspectRepository(f.root), env: f.env }), { code: 'APPROVAL_REQUIRED' });
assert.equal(restoreProject({ repository: inspectRepository(f.root), env: f.env, authorized: true }).sessionsStarted, false);
assert.equal(JSON.parse(readFileSync(metadataPath)).detachedAt, null);
assert.equal(readFileSync(join(f.root, '.torch/torch.yaml'), 'utf8'), config);
assert.deepEqual(manifest.external.filter(entry => entry.type === 'worktree').map(entry => git(entry.path, ['rev-parse', 'HEAD'])), heads);
});
+1 -1
View File
@@ -1,6 +1,6 @@
{
"schema": "torch.dev/release/v1alpha1",
"version": "0.1.0-alpha.1",
"version": "0.1.0-alpha.2",
"state": {
"reads": ["torch.dev/state/v1alpha1"],
"writes": "torch.dev/state/v1alpha1",