mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
[ai] Route oversized tasks through durable splits
This commit is contained in:
@@ -52,14 +52,21 @@ The canonical lifecycle is deliberately small:
|
||||
- `todo` with `claimed_by: null` is ready shared work;
|
||||
- `in-progress` with this `checkout_tag` is this checkout's one active task;
|
||||
- `blocked` with this tag is a rare published unfinished boundary;
|
||||
- `split-required` with this tag is a published performer result awaiting one
|
||||
scheduler-owned split transaction;
|
||||
- `approved` is the only completed terminal state.
|
||||
|
||||
After routing, the retired source has no live state: its sealed `split.yaml`
|
||||
records all successors and the optional implementation carrier. This is
|
||||
terminal history, not another runnable status.
|
||||
|
||||
`Start` atomically assigns an unclaimed task and changes it to `in-progress`.
|
||||
Normal phase artifacts remain local and uncommitted in the slot worktree.
|
||||
`Approve` publishes all final AI artifacts and state in one commit. `Block` is
|
||||
permitted only for a genuine exhausted task blocker,
|
||||
not for an interrupted agent session. Never publish `Claim`, phase checkpoint,
|
||||
or `Resume` commits. Existing claimed `todo` records from the older workflow
|
||||
not for an interrupted agent session. `Split-required` publishes the proposal
|
||||
and seals any retained source work for the scheduler transaction. Never publish
|
||||
`Claim`, phase checkpoint, or `Resume` commits. Existing claimed `todo` records from the older workflow
|
||||
remain startable but do not justify creating new reservations.
|
||||
|
||||
Never infer ownership from an inbox receipt. Do not steal work from another
|
||||
@@ -76,8 +83,18 @@ the queue. A repeated pre-commit race may remain pending for the next
|
||||
invocation; record that marker as attempted and do not spin. If a task is
|
||||
already active, its expected local phase files make the shared AI slot unsafe
|
||||
for consolidation: freeze and finish that active task first, then recover all
|
||||
pending markers at its clean canonical `Approve` or `Block` boundary before
|
||||
selecting more work.
|
||||
pending markers at its clean canonical `Approve`, `Block`, or completed split
|
||||
routing boundary before selecting more work.
|
||||
|
||||
After recovering pending consolidations and before freezing a new batch, route
|
||||
this checkout's `own_split_required` task, when any, through the dedicated split
|
||||
worker below. Refresh the queue afterward and freeze the resulting replacement
|
||||
tasks at the front of the initial batch regardless of a scope hint; they replace
|
||||
checkout work that hints cannot exclude. Record that startup split for the
|
||||
invocation summary. A split-required task is exclusive checkout work: do not
|
||||
start, retry, or resume another task while it remains unrouted. If its retained
|
||||
source state cannot be transferred safely, stop with that state intact rather
|
||||
than skipping it.
|
||||
|
||||
## Interpret scope hints
|
||||
|
||||
@@ -87,7 +104,8 @@ preference such as "payments tasks first" reorders the shared tasks recorded
|
||||
in the startup batch; it does not exclude the others. A restriction such as
|
||||
"only the payments tasks" or "all tasks except projects X and Y" records only
|
||||
matching unclaimed shared tasks.
|
||||
Hints never exclude this checkout's active, blocked, or legacy-reserved work.
|
||||
Hints never exclude this checkout's active, split-required, blocked, or
|
||||
legacy-reserved work.
|
||||
A restrictive hint that matches no shared task does not make an existing
|
||||
queue look idle or permit inbox processing.
|
||||
|
||||
@@ -113,7 +131,9 @@ these invocation-local values in the scheduler plan:
|
||||
- ordered `batch_task_ids`, initially equal to the initial batch;
|
||||
- empty `discovered_task_ids`;
|
||||
- empty `consolidation_mappings` and `consolidation_receipts`;
|
||||
- empty `attempted_blocked`.
|
||||
- empty `attempted_blocked`;
|
||||
- `split_records`, initialized with any startup split transaction and otherwise
|
||||
empty.
|
||||
|
||||
Do not write a batch file, claim the whole batch, or publish reservations.
|
||||
Queue refreshes update task state but never add ordinary task ids to the
|
||||
@@ -170,14 +190,15 @@ would record from the startup snapshot:
|
||||
- only matching unclaimed tasks under a restrictive hint.
|
||||
|
||||
Record dependency-waiting tasks too. Finish the active task to an approved,
|
||||
genuinely blocked, or global-hard-stop boundary, then continue through ready
|
||||
recorded tasks one at a time. Only an explicit request to run just the active
|
||||
genuinely blocked, split-required, or global-hard-stop boundary, route any
|
||||
split before continuing, then continue through ready recorded tasks one at a
|
||||
time. Only an explicit request to run just the active
|
||||
task produces a one-item active batch.
|
||||
|
||||
### Mode 2: drain the existing queue snapshot
|
||||
|
||||
When there is no active task but any `own_blocked`, `own_todo`, or
|
||||
`unclaimed_todo` task exists, choose `queue` mode. Record:
|
||||
When there is no active or split-required task but any `own_blocked`,
|
||||
`own_todo`, or `unclaimed_todo` task exists, choose `queue` mode. Record:
|
||||
|
||||
- every own blocked and legacy-reserved task, regardless of the hint;
|
||||
- every unclaimed task under no hint or a preference, ordered with preferred
|
||||
@@ -194,8 +215,9 @@ recorded batch drains.
|
||||
|
||||
### Mode 3: bootstrap from the inbox
|
||||
|
||||
Choose `inbox` mode only when `own_in_progress`, `own_blocked`, `own_todo`,
|
||||
and `unclaimed_todo` were all empty in the initial snapshot. Work owned by
|
||||
Choose `inbox` mode only when `own_in_progress`, `own_split_required`,
|
||||
`own_blocked`, `own_todo`, and `unclaimed_todo` were all empty in the initial
|
||||
snapshot. Work owned by
|
||||
another checkout is not work this checkout can drain and does not enter its
|
||||
batch.
|
||||
|
||||
@@ -226,8 +248,12 @@ claimed concurrently, blocked by an external dependency, or otherwise
|
||||
unavailable.
|
||||
|
||||
Before publishing any new canonical `Start` commit, require a clean Telegram
|
||||
source checkout with clean submodules and no unrelated untracked files. Do not
|
||||
require a Telegram executable, portable account, desktop, Docker daemon, or
|
||||
source checkout with clean submodules and no unrelated untracked files. The one
|
||||
exception is the checkout-owned first replacement whose `carried_from` field
|
||||
and source `split.yaml` designate it as the implementation carrier: start it
|
||||
with the retained source state intact, and let the helper revalidate the sealed
|
||||
worktree before transferring task refs. Do not require a Telegram executable,
|
||||
portable account, desktop, Docker daemon, or
|
||||
other instrument before assessment selects it. The performer gates every
|
||||
selected instrument before using it and records an unavailable platform or
|
||||
stage precisely instead of preventing unrelated task work from starting.
|
||||
@@ -240,7 +266,18 @@ resumption handoff. There must be at most one active task. Stop on an active
|
||||
task outside the batch instead of silently expanding the batch or stealing
|
||||
ownership.
|
||||
|
||||
### 2. Retry recorded blocked work
|
||||
### 2. Start a carried implementation
|
||||
|
||||
Otherwise select the first ready checkout-owned `todo` task in
|
||||
`batch_task_ids` whose `carried_from` field names a retired split task. It must
|
||||
be the first replacement and match that task's `implementation_carrier`.
|
||||
Start it with the normal helper command. The helper verifies the source
|
||||
worktree seal, transfers the old task's base/green/run refs, publishes the
|
||||
carrier's canonical `Start`, and removes the obsolete refs. If any check fails,
|
||||
hard-stop with both the carrier and retained source state intact; do not start
|
||||
another batch task around it.
|
||||
|
||||
### 3. Retry recorded blocked work
|
||||
|
||||
Otherwise select the first ready task in `own_blocked` whose id is in
|
||||
`batch_task_ids` and not in `attempted_blocked`. Readiness means every
|
||||
@@ -261,7 +298,7 @@ genuine new `Block` boundary under the validation below. A test-campaign cap,
|
||||
`TEST_FLAW`, blank/missing evidence, or another recoverable harness failure is
|
||||
not genuine and does not consume this invocation's blocked retry.
|
||||
|
||||
### 3. Start recorded reserved work
|
||||
### 4. Start recorded reserved work
|
||||
|
||||
Otherwise select the first ready legacy `todo` task already owned by this
|
||||
checkout whose id is in `batch_task_ids`, and start it:
|
||||
@@ -275,7 +312,7 @@ The resulting canonical `Start` commit changes it to `in-progress`. Leave
|
||||
legacy reservations with unfinished dependencies untouched and consider later
|
||||
ready batch work.
|
||||
|
||||
### 4. Start recorded shared work
|
||||
### 5. Start recorded shared work
|
||||
|
||||
Otherwise select the first ready unclaimed `todo` task whose id is in
|
||||
`batch_task_ids`, using the order recorded at startup. Start it with the same
|
||||
@@ -286,11 +323,12 @@ A concurrent start may mean another checkout won the task. Never overwrite
|
||||
shared state or replace it with a task outside the batch; refresh and continue
|
||||
with another recorded id.
|
||||
|
||||
### 5. Stop normally
|
||||
### 6. Stop normally
|
||||
|
||||
Stop when none of these batch-scoped conditions exist:
|
||||
|
||||
- this checkout's active batch task;
|
||||
- a ready recorded carried implementation;
|
||||
- a ready recorded blocked task not attempted in this invocation;
|
||||
- a ready recorded legacy-reserved task;
|
||||
- a ready recorded unclaimed task.
|
||||
@@ -327,9 +365,9 @@ Source checkout: <source_root>
|
||||
AI slot worktree: <slot_worktree>
|
||||
Checkout tag: <checkout_tag>
|
||||
Task: <task-id>
|
||||
Own this task until it is approved, genuinely blocked, or reaches a global
|
||||
hard stop. You may use the bounded leaf delegation required by the skill. Do
|
||||
not select or start another task.
|
||||
Own this task until it is approved, genuinely blocked, split-required, or
|
||||
reaches a global hard stop. You may use the bounded leaf delegation required by
|
||||
the skill. Do not select or start another task.
|
||||
```
|
||||
|
||||
The performer is stateful. Never duplicate it. Poll at no more than 60-second
|
||||
@@ -342,23 +380,42 @@ After it returns, require one of:
|
||||
canonical AI master;
|
||||
- source checkout clean and task exceptionally `blocked` on canonical master,
|
||||
with exact unverified behavior;
|
||||
- a pre-source `Scope: split-required` or review-convergence
|
||||
`RESCOPE_REQUIRED` boundary with `work/split-proposal.md`, leaving the task
|
||||
`in-progress` and all source/task recovery intact; or
|
||||
- task `split-required` on canonical AI master with `work/split-proposal.md`
|
||||
and `work/carried-work.json`, leaving every retained source change and task
|
||||
ref sealed for transfer; or
|
||||
- a clearly reported global hard stop, leaving the task `in-progress` and all
|
||||
task-scoped local state recoverable for the next invocation.
|
||||
|
||||
A rescope boundary stops task performance and is not retried, approved, blocked,
|
||||
or routed as an ordinary discovered follow-up. The scheduler is the queue
|
||||
authority: it independently checks that the proposal contains separately
|
||||
shippable/testable boundaries and a coherent dependency graph before any
|
||||
dedicated rescope transaction or human handoff. It never treats the performer's
|
||||
proposal alone as permission to delete source or rewrite shared task state. On
|
||||
a later invocation, a performer that finds the same unresolved boundary returns
|
||||
it immediately without rerunning planning, review, builds, or tests. Inbox
|
||||
planning prevents most new oversized tasks; replacing an already-active task
|
||||
and deciding how to salvage its source requires that explicit scheduler-owned
|
||||
transaction, not ordinary discovery routing.
|
||||
A rescope result stops task performance and is not retried, approved, blocked,
|
||||
or routed as an ordinary discovered follow-up. The performer's publication is
|
||||
the durable request for the scheduler-owned transaction below; it is not
|
||||
permission to delete source or flatten several successors into one alias.
|
||||
|
||||
## Route a split-required result
|
||||
|
||||
When a batch performer publishes `split-required`, immediately spawn one fresh
|
||||
split worker with `fork_turns: "none"`. Give it `source_root`, `slot_worktree`,
|
||||
`checkout_tag`, the source task id, and the current ordered batch. Tell it not
|
||||
to delegate and to read
|
||||
`.agents/skills/continue/references/split-required-task.md` completely. It may
|
||||
inspect Telegram source and edit/publish AI task, project, dependency, and
|
||||
receipt state; it must not edit, reset, stash, commit, build, or test Telegram
|
||||
source.
|
||||
|
||||
Validate its canonical `Split <source-id>` result and refreshed queue. Replace
|
||||
the source id in `batch_task_ids` at its existing position with the ordered
|
||||
replacement ids, removing duplicates; leave `initial_batch_task_ids` unchanged.
|
||||
Append the source, replacements, carrier, and receipt to `split_records`. The
|
||||
replacements are part of this invocation because they replace an existing batch
|
||||
member, not because later queue refreshes normally expand the frozen batch.
|
||||
|
||||
When a carrier exists it must be first, checkout-owned `todo`, and name the
|
||||
source in `carried_from`; select it through the carried-implementation step
|
||||
before any blocked, reserved, or shared task. Starting it performs the sealed
|
||||
source-ref transfer. When no carrier exists, all replacements are ordinary
|
||||
unclaimed `todo`. A split publication race is retried normally. A semantic
|
||||
conflict, unavailable remote, changed worktree seal, or incoherent carrier is a
|
||||
global hard stop with the source result and implementation left recoverable.
|
||||
|
||||
Before accepting a canonical test block, read `work/result.md` and
|
||||
`work/test.md`. It is genuine only when the verdict is not `TEST_FLAW`, does
|
||||
@@ -543,7 +600,8 @@ this invocation, and continue without treating the optimization as a blocker.
|
||||
If the worker created a commit that cannot be published safely, preserve it and
|
||||
hard-stop exactly as for discovery routing.
|
||||
|
||||
At every clean canonical `Approve` or `Block` boundary, process any older
|
||||
At every clean canonical `Approve`, `Block`, or completed split routing
|
||||
boundary, process any older
|
||||
pending marker deferred by an active startup task before selecting more work,
|
||||
then process the marker just created by that task's routing. Attempt each marker
|
||||
at most once per invocation.
|
||||
@@ -562,7 +620,8 @@ Return one compact summary: invocation mode, initial batch ids, discovered ids
|
||||
added to the batch, inbox receipt if processed, tasks approved, exceptionally
|
||||
blocked tasks with exact unverified behavior and retry status, recorded tasks
|
||||
left queued, unrelated new tasks deferred to the next invocation, routed
|
||||
discoveries, infrastructure-limited coverage gaps recorded but not routed,
|
||||
discoveries, split-required sources with ordered replacements and carriers,
|
||||
infrastructure-limited coverage gaps recorded but not routed,
|
||||
consolidation no-merge results or receipts, old-to-new mappings, the net
|
||||
task-count saving, archived projects, any discarded interrupted-worker leftovers,
|
||||
elapsed time, and why the loop stopped. Make any global hard stop or unsafe
|
||||
|
||||
111
.agents/skills/continue/references/split-required-task.md
Normal file
111
.agents/skills/continue/references/split-required-task.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Route a split-required task
|
||||
|
||||
Run this only from the `continue` scheduler for one task already published as
|
||||
`status: split-required`. It is a deep task-routing transaction, not task
|
||||
implementation. Inspect Telegram source and the retained implementation, but
|
||||
do not edit, reset, stash, commit, build, or test Telegram source.
|
||||
|
||||
## Read the retained task
|
||||
|
||||
Read the source task's complete `task.md`, project context, dependencies,
|
||||
`work/context.md`, `work/plan.md`, `work/split-proposal.md`, `work/result.md`,
|
||||
and `work/carried-work.json`. Inspect the complete retained source diff and
|
||||
the relevant adjacent code. The proposal is input, not a set of titles to copy
|
||||
blindly: refine it into the smallest independently shippable and independently
|
||||
testable product boundaries.
|
||||
|
||||
Each replacement must have one useful outcome, a direct acceptance oracle, and
|
||||
enough self-contained context to run without this routing session. Split at
|
||||
network, persistence, engine, ownership/lifetime, lifecycle, UI, platform, or
|
||||
evidence boundaries when they can stand on their own. Keep inseparable APIs and
|
||||
their only callers together. Add a final integration task only when integration
|
||||
has behavior not already proved by the component tasks.
|
||||
|
||||
Preserve the source task's project by default. A replacement may leave that
|
||||
project only when it remains coherent, implementable, and testable with the
|
||||
project changes absent. Preserve the source task's existing dependencies where
|
||||
their code is still required. Order replacement dependencies by actual shipped
|
||||
code or behavior, not by the order in which the plan happened to mention them.
|
||||
|
||||
## Preserve existing implementation
|
||||
|
||||
`work/carried-work.json` records whether source implementation exists and seals
|
||||
the owned working diff. When it says `implementation: retained`, designate
|
||||
exactly one first replacement as the implementation carrier. Shape that task so
|
||||
the whole retained diff is inside a coherent boundary it can inspect, correct,
|
||||
review, build, and test. If the diff spans the future slices, a real first task
|
||||
that stabilizes and proves the shared foundation is appropriate; an unreviewed
|
||||
checkpoint or a task whose only result is storing the patch is not.
|
||||
|
||||
The carrier's `task.md` must name the split source task, tell the performer to
|
||||
read its retained artifacts and complete source diff, and state which current
|
||||
implementation it adopts. Later replacements depend on the carrier whenever
|
||||
they consume that code. Create the carrier initially as pristine unclaimed
|
||||
`todo`; the publication helper transfers its reservation and
|
||||
`owned-paths.txt`. Do not copy phase conclusions as approvals: the carrier runs
|
||||
its own focused planning, complete review, and evidence loop over the retained
|
||||
implementation.
|
||||
|
||||
Do not discard existing implementation merely because a cleaner decomposition
|
||||
would have started differently. Do not reset it, hide it in an ignored patch,
|
||||
or split it into unreviewed commits during routing. If no coherent carrier can
|
||||
own it, stop with the split-required task and source state untouched and report
|
||||
the exact conflict for a human decision.
|
||||
|
||||
When `implementation: none`, create no carrier and leave every replacement
|
||||
unclaimed.
|
||||
|
||||
## Write replacement state
|
||||
|
||||
Create at least two dated replacement task directories using the ordinary
|
||||
`process-inbox` task and state schemas. Every replacement uses `type: implement`
|
||||
and names the split receipt in `inbox_receipt`. Before publication every state
|
||||
is pristine unclaimed `todo` and omits or sets `carried_from: null`; the helper
|
||||
sets the carrier's durable ownership transfer.
|
||||
|
||||
Write one receipt under `receipts/YYYY/MM/DD/` containing:
|
||||
|
||||
- the split source id and why one campaign was incoherent;
|
||||
- every replacement id, shipped boundary, acceptance oracle, and dependency;
|
||||
- the implementation carrier or `none`;
|
||||
- how every original acceptance criterion and retained source path is owned;
|
||||
- every changed dependent and project link.
|
||||
|
||||
Replace the source task's link in its project index with the replacement links
|
||||
in dependency/routing order. Rewrite every live task dependency on the source
|
||||
to the exact successor or successors that provide the needed behavior. A
|
||||
retired split id must remain in neither a live dependency nor a project index.
|
||||
Do not edit the source task directory; the helper replaces only its
|
||||
`state.yaml` with a sealed multi-target `split.yaml`.
|
||||
|
||||
## Validate and publish
|
||||
|
||||
Check the complete dependency graph, task links, projects, receipt, native text
|
||||
format, and absence of persisted commit hashes. Then publish through:
|
||||
|
||||
```bash
|
||||
python3 .agents/skills/process-inbox/scripts/workspace.py split-publish \
|
||||
--source-task <source-id> \
|
||||
--receipt <receipts/YYYY/MM/DD/split-receipt.md> \
|
||||
--replacement <first-id> \
|
||||
--replacement <next-id> \
|
||||
[--implementation-carrier <first-id>] \
|
||||
--path <tasks/source-id> \
|
||||
--path <tasks/first-id> \
|
||||
--path <tasks/next-id> \
|
||||
--path <each-changed-project-dependent-or-receipt-path>
|
||||
```
|
||||
|
||||
Use the host's available Python 3 command. The helper rechecks the sealed source
|
||||
worktree, replacement state, receipt, project indexes, full dependency graph,
|
||||
and retained source-task digest. It publishes `Split <source-id>`. With a
|
||||
carrier, it leaves the source refs and working implementation intact and makes
|
||||
the carrier a checkout-owned `todo`; the scheduler must select it first and use
|
||||
the normal `start` command, which rechecks the worktree seal, transfers the refs,
|
||||
and publishes the carrier's canonical `Start`. Without a carrier the helper
|
||||
removes the obsolete source refs after publication.
|
||||
|
||||
On an ordinary publication race, retry through the helper. Preserve an
|
||||
unpublished split commit on semantic conflict or remote outage. Report the
|
||||
source id, ordered replacements, carrier, receipt, publication state, and any
|
||||
hard stop; never report commit hashes.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: perform-task
|
||||
description: Resolve, start or resume, implement, review, test, and publish exactly one existing ai-tdesktop task by short slug or full dated id, including rare blocked unfinished work. Use when the user invokes $perform-task or /perform-task with a known task name, or when the continue scheduler delegates one selected task. Runs standard review lenses with fast applicability bailouts and selects task-specific domain and evidence instruments without selecting additional work.
|
||||
description: Resolve, start or resume, implement, review, test, and publish exactly one existing ai-tdesktop task by short slug or full dated id, including rare blocked retries and split-required results. Use when the user invokes $perform-task or /perform-task with a known task name, or when the continue scheduler delegates one selected task. Runs standard review lenses with fast applicability bailouts and selects task-specific domain and evidence instruments without selecting additional work.
|
||||
---
|
||||
|
||||
# Perform One AI Task
|
||||
@@ -10,7 +10,8 @@ before any other host-specific delegation rule and apply its substitutions.
|
||||
|
||||
Own exactly one task through its retained change, or a proved
|
||||
`already-satisfied` outcome, and a canonical AI `Approve` or exceptional
|
||||
`Block`. Do not process the inbox, split the task, drain the queue,
|
||||
`Block`, or a canonical `Split-required` result. Do not process the inbox,
|
||||
create replacement tasks, drain the queue,
|
||||
select a follow-up, or consolidate pending tasks afterward. The `continue`
|
||||
scheduler isolates discovery routing and queue consolidation in fresh workers
|
||||
after this performer returns.
|
||||
@@ -62,6 +63,9 @@ Inspect the resolved task, readiness, `other_active_task`, status, and owner.
|
||||
|
||||
- If another task is already `in-progress` for this checkout, stop.
|
||||
- If this task is `approved`, report its completed result and stop.
|
||||
- If it is `split-required`, report its published split proposal and stop. A
|
||||
direct invocation leaves routing to the human; a scheduler invocation returns
|
||||
control so `continue` can launch the dedicated split worker.
|
||||
- If it is owned by another checkout, stop. Cross-checkout restart is a rare
|
||||
explicit human reassignment, never an implicit steal.
|
||||
- If its dependencies are unfinished, report them and stop without starting.
|
||||
@@ -109,7 +113,7 @@ the scheduler may continue work that does not depend on it.
|
||||
## Run and publish
|
||||
|
||||
Execute `references/pipeline.md` exactly. A task that changes the repository
|
||||
produces:
|
||||
and is approved produces:
|
||||
|
||||
1. one or more tested source implementation-attempt commits, each with an
|
||||
exact one-line subject using the pipeline's conditional `[ai] ` prefix,
|
||||
@@ -123,12 +127,16 @@ New and unfinished tasks use the single adaptive `implement` path. Assessment
|
||||
must first confirm that the request is one cohesive implementation/review/test
|
||||
unit. If it contains independently useful and independently testable product
|
||||
boundaries, record `Scope: split-required` and a concrete split proposal before
|
||||
source edits, then stop for queue rescoping; do not force the broad request
|
||||
through smaller implementation phases and call it one task. The independent
|
||||
assessment has veto authority over implementation, not authority to create,
|
||||
retire, or rewrite tasks. The performer validates and preserves the proposal;
|
||||
the checkout scheduler owns any later queue mutation. A direct invocation
|
||||
returns the proposal to the human.
|
||||
source edits. The same result may arise later from the bounded convergence
|
||||
assessment when the retained implementation proves that one review/evidence
|
||||
campaign is not coherent. Do not force the broad request through smaller
|
||||
implementation phases and call it one task. The independent assessment has
|
||||
veto authority over further implementation, not authority to create, retire,
|
||||
or rewrite tasks. The performer writes the split result, preserves any owned
|
||||
implementation and source refs, and publishes it with
|
||||
`finish --status split-required`. The checkout scheduler owns the later queue
|
||||
mutation and implementation transfer. A direct invocation returns the
|
||||
published proposal to the human.
|
||||
|
||||
For a cohesive task, use one mandatory general review, all five standard review
|
||||
lenses, and a falsifiable evidence plan. On the initial implementation the
|
||||
|
||||
@@ -350,6 +350,9 @@ independent assessor has veto authority because it is the first phase with the
|
||||
exact implementation and evidence plan. It does not create, retire, supersede,
|
||||
or rewrite queue tasks; the performer preserves the proposal and returns it to
|
||||
the scheduler, which owns any rescope transaction.
|
||||
The performer does not leave this as an unpublished `in-progress` marker: after
|
||||
validating the proposal it writes the split result and calls
|
||||
`finish --status split-required`, preserving any owned source state.
|
||||
|
||||
```text
|
||||
You are a plan assessment agent. Review and refine an implementation plan.
|
||||
@@ -908,6 +911,11 @@ blocking findings, stop with its unapproved artifacts; do not begin another
|
||||
campaign automatically.
|
||||
~~~
|
||||
|
||||
On `RESCOPE_REQUIRED`, the performer validates `split-proposal.md`, inventories
|
||||
all retained owned source paths, writes the canonical split result, and calls
|
||||
`finish --status split-required`. It does not clean or checkpoint source work;
|
||||
the scheduler's later split worker assigns the sealed implementation carrier.
|
||||
|
||||
### Review fix
|
||||
|
||||
~~~text
|
||||
|
||||
@@ -277,9 +277,12 @@ Run sequentially:
|
||||
approach rejection with the assessor's simpler direction as added input —
|
||||
or the terminal pre-edit `Scope: split-required` planning boundary.
|
||||
This assessor has authority to veto source implementation because it has the
|
||||
first exact implementation/evidence plan. It cannot mutate task state beyond
|
||||
its local artifacts or create replacement tasks; the scheduler independently
|
||||
validates and owns rescoping.
|
||||
first exact implementation/evidence plan. It cannot create replacement tasks;
|
||||
the performer publishes the proposal as the task's `split-required` result,
|
||||
and the scheduler independently owns the deep split transaction. The same
|
||||
result may be produced after source edits by the bounded convergence
|
||||
assessment when the retained implementation exposes several independently
|
||||
shippable/testable boundaries.
|
||||
3. **Implement.** Run one leaf per assessed plan phase. Before each edit,
|
||||
update `work/owned-paths.txt`. A leaf edits only its owned paths and its
|
||||
phase status; it does not commit.
|
||||
@@ -718,14 +721,22 @@ behavior. `Blocker-Type: test` additionally requires `work/test.md` to contain
|
||||
Computer Use infrastructure-unavailable case. A `TEST_FLAW`, a run cap, or a
|
||||
missing capture can never be the blocked verdict.
|
||||
|
||||
For `split-required`, do not clean, reset, stash, or checkpoint retained source
|
||||
implementation. Require current task base/run refs, keep the owned diff and any
|
||||
green commit in place, and inventory every owned path in `work/owned-paths.txt`.
|
||||
The publication helper seals that work in `work/carried-work.json`; the later
|
||||
split transaction rechecks the seal before assigning an implementation carrier.
|
||||
|
||||
Write `work/result.md` with exactly one value for every field:
|
||||
|
||||
```text
|
||||
# Task result: <TASK_ID>
|
||||
STATUS: DONE | BLOCKED
|
||||
Outcome: changed | already-satisfied | blocked
|
||||
Verdict: APPROVED | <specific blocker>
|
||||
STATUS: DONE | BLOCKED | SPLIT_REQUIRED
|
||||
Outcome: changed | already-satisfied | blocked | split-required
|
||||
Verdict: APPROVED | SPLIT_REQUIRED | <specific blocker>
|
||||
Blocker-Type: none | test | impl | unrecoverable
|
||||
Implementation: retained | none
|
||||
Split-Proposal: work/split-proposal.md | none
|
||||
Attempts: <n>
|
||||
Test-Runs: <n>
|
||||
UI-Driver: overlay | hybrid | mixed | hybrid-unavailable | not-applicable
|
||||
@@ -733,7 +744,7 @@ Touched: <source paths or none>
|
||||
Test-Report: work/test.md
|
||||
Evidence: <tracked evidence paths and what they prove>
|
||||
Unverified: none | <exact behavior and manual follow-up>
|
||||
Checkout: clean-buildable | unsafe
|
||||
Checkout: clean-buildable | source-state-retained | unsafe
|
||||
Discovered: none | present
|
||||
|
||||
## Discovered tasks
|
||||
@@ -746,6 +757,14 @@ source commit, and direct evidence that the requested proposition held before
|
||||
the task. A blocked result uses `Outcome: blocked` and retains a latest safe
|
||||
implementation attempt when one exists.
|
||||
|
||||
A split result uses `STATUS: SPLIT_REQUIRED`, `Outcome: split-required`,
|
||||
`Verdict: SPLIT_REQUIRED`, `Blocker-Type: none`, and
|
||||
`Split-Proposal: work/split-proposal.md`. Set `Implementation: retained` and
|
||||
name its paths under `Touched:` when owned source work exists; otherwise use
|
||||
`Implementation: none` and `Touched: none`. It uses
|
||||
`Checkout: source-state-retained` and does not require a test report, because
|
||||
each replacement receives its own complete review and evidence campaign.
|
||||
|
||||
For approved project work, promote `work/project.proposed.md` to the project's
|
||||
`project.md` immediately before final AI publication. For blocked work, retain
|
||||
the proposal only as a task artifact.
|
||||
@@ -755,7 +774,7 @@ Publish final AI state only after the Telegram commit and result are final:
|
||||
```bash
|
||||
python3 SOURCE_ROOT/.agents/skills/process-inbox/scripts/workspace.py \
|
||||
finish --source-root SOURCE_ROOT --task TASK_ID \
|
||||
--status approved|blocked --model MODEL_SHORT_NAME
|
||||
--status approved|blocked|split-required --model MODEL_SHORT_NAME
|
||||
```
|
||||
|
||||
`--model` is required and records which model finished the task, into the
|
||||
@@ -768,14 +787,17 @@ resumed by a different model after an interruption records the model that
|
||||
actually completed it. Never guess or copy the value from another task; if you
|
||||
cannot tell what you are, say so and stop rather than recording a wrong name.
|
||||
|
||||
The helper verifies a clean source checkout, local task refs, current `HEAD`,
|
||||
and either the retained implementation's exact three-line commit message or
|
||||
the strict no-change state required by `already-satisfied`. It commits
|
||||
all task-scoped local artifacts and final state as `Approve <TASK_ID>` or the
|
||||
exceptional `Block <TASK_ID>`, fetches newer canonical state when configured,
|
||||
For approval or Block, the helper verifies a clean source checkout, local task
|
||||
refs, current `HEAD`, and either the retained implementation's exact three-line
|
||||
commit message or the strict no-change state required by `already-satisfied`.
|
||||
For split-required it verifies current refs, seals the owned working state, and
|
||||
does not require a clean source checkout. It commits all task-scoped local
|
||||
artifacts and final state as `Approve <TASK_ID>`, exceptional
|
||||
`Block <TASK_ID>`, or `Split-required <TASK_ID>`, fetches newer canonical state when configured,
|
||||
rebases the slot, publishes without force, and fast-forwards local AI master.
|
||||
It deletes all local task refs after approval; after a block it deletes only
|
||||
`RUN_REF` and retains implementation recovery refs for the next invocation.
|
||||
`RUN_REF` and retains implementation recovery refs for the next invocation;
|
||||
after split-required it retains all refs for the scheduler's carrier transfer.
|
||||
Do not report final state until that AI commit reaches canonical master.
|
||||
Preserve an unpublished final slot commit on a semantic conflict or remote
|
||||
outage and hard-stop instead of pretending completion.
|
||||
@@ -825,13 +847,13 @@ delays finishing the work actually in hand.
|
||||
|
||||
- `Scope: split-required` before source edits and `RESCOPE_REQUIRED` from a
|
||||
convergence assessment are planning boundaries, not task `Block` verdicts
|
||||
and not permission to keep retrying. Preserve `split-proposal.md`, all
|
||||
validated source recovery, and the task's `in-progress` state; return the
|
||||
proposal to the scheduler (or human for a direct invocation) and stop
|
||||
automatic performance until the queue is deliberately replaced. Assessment
|
||||
owns the stop; only the scheduler owns task creation, dependency rewrites,
|
||||
and superseding the original. A resumed performer that sees the same
|
||||
unresolved boundary reports it immediately without rerunning context,
|
||||
and not permission to keep retrying. Preserve `split-proposal.md`, all owned
|
||||
implementation and source recovery, write the split result, and publish
|
||||
`finish --status split-required`; then return control to the scheduler (or
|
||||
human for a direct invocation). Assessment owns the stop; only the scheduler
|
||||
owns task creation, dependency rewrites, implementation-carrier transfer,
|
||||
and retiring the original. A performer resolving an already published
|
||||
split-required task reports it immediately without rerunning context,
|
||||
implementation, review, or builds.
|
||||
- Source lineage has a strict timing boundary. Before Phase 1, a missing
|
||||
approved prerequisite is a clean pre-phase routing stop: do not publish
|
||||
|
||||
@@ -63,6 +63,10 @@ paths. Follow `superseded_by` chains to their live task when deduplicating,
|
||||
resolving prior receipt references, or checking whether a same-digest result
|
||||
still exists. New dependencies and project links must name the final live task,
|
||||
never an alias. A dated slug occupied by an alias still counts as a collision.
|
||||
Some retired oversized tasks instead have `split.yaml`, whose `split_into`
|
||||
list resolves to several live successors. Treat the retained directory as
|
||||
history, deduplicate against all live successors, and never put the split id in
|
||||
a new dependency or project link. A split path is also permanently occupied.
|
||||
|
||||
Use one disposable leaf planner when the harness supports delegation; instruct
|
||||
it not to delegate. Otherwise perform the same work locally. The planner may
|
||||
@@ -136,7 +140,10 @@ files, APIs, phases, ownership boundaries, and evidence design; it may veto the
|
||||
single-task shape when that richer proof exposes independently shippable and
|
||||
testable boundaries. That veto does not mean task sizing is based on elapsed
|
||||
time or diff length, and it does not authorize the performer to mutate the
|
||||
queue itself.
|
||||
queue itself. The performer publishes `split-required`; the checkout scheduler
|
||||
then launches a dedicated deep split transaction that creates replacements,
|
||||
rewrites dependencies and project links, and retires the source with a durable
|
||||
multi-target split record.
|
||||
|
||||
Project slugs are unique across `projects/` and `projects/archive/`. When a
|
||||
request belongs to an archived project, restore it before routing to it:
|
||||
@@ -224,11 +231,13 @@ claimed_at: null
|
||||
claim_order: null
|
||||
lease_until: null
|
||||
phase: null
|
||||
carried_from: null
|
||||
inbox_receipt: receipts/YYYY/MM/DD/<receipt>.md
|
||||
```
|
||||
|
||||
Do not write a `model` field. It records which model finished the task, so only
|
||||
`finish` writes it, at the canonical `Approve` or `Block` boundary; a task
|
||||
`finish` writes it, at the canonical `Approve`, `Block`, or `Split-required`
|
||||
boundary; a task
|
||||
carrying one before it is claimed is malformed.
|
||||
|
||||
Use a project slug instead of `null` when routed to a project. Use a YAML list
|
||||
@@ -263,9 +272,9 @@ Create one tracked Markdown receipt under `receipts/YYYY/MM/DD/`. Include:
|
||||
- deduplication decisions.
|
||||
|
||||
Before writing, search receipts for the same digest. If it was already fully
|
||||
processed and every referenced task either has live state or has a durable alias
|
||||
chain reaching live state, create nothing and reuse that receipt for
|
||||
finalization.
|
||||
processed and every referenced task either has live state, has a durable alias
|
||||
chain reaching live state, or has a durable split record whose successors all
|
||||
resolve to live state, create nothing and reuse that receipt for finalization.
|
||||
|
||||
## Validate and publish
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2898,6 +2898,226 @@ class MechanicsTest(unittest.TestCase):
|
||||
self.assertTrue(result["golden_account_present"])
|
||||
self.assertFalse(result["live_marker_present"])
|
||||
|
||||
def test_finish_publishes_split_required_with_carried_work(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
source, slot, work, config = source_repo_with_task(root)
|
||||
config["slot_worktree"] = str(slot)
|
||||
for name in ("base", "run"):
|
||||
git(
|
||||
source,
|
||||
"update-ref",
|
||||
workspace.source_task_ref(TASK_ID, name),
|
||||
"HEAD",
|
||||
)
|
||||
(work / "owned-paths.txt").write_text(
|
||||
"tracked.txt\n", encoding="utf-8",
|
||||
)
|
||||
(work / "split-proposal.md").write_text(
|
||||
"# Split proposal\n\nTwo independent boundaries.\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(work / "result.md").write_text(
|
||||
"""STATUS: SPLIT_REQUIRED
|
||||
Outcome: split-required
|
||||
Verdict: SPLIT_REQUIRED
|
||||
Implementation: retained
|
||||
Touched: tracked.txt
|
||||
Split-Proposal: work/split-proposal.md
|
||||
Checkout: source-state-retained
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(source / "tracked.txt").write_text("carried\n", encoding="utf-8")
|
||||
with (
|
||||
mock.patch.object(
|
||||
workspace,
|
||||
"task_action_config",
|
||||
return_value=(config, slot),
|
||||
),
|
||||
mock.patch.object(workspace, "commit_paths", return_value=True),
|
||||
):
|
||||
result = run_command(
|
||||
workspace.command_finish,
|
||||
task=TASK_ID,
|
||||
status="split-required",
|
||||
model="gpt-5.6-sol",
|
||||
)
|
||||
|
||||
state = workspace.load_state(slot, work.parent / "state.yaml")
|
||||
self.assertEqual(result["status"], "split-required")
|
||||
self.assertEqual(state["status"], "split-required")
|
||||
self.assertEqual(state["phase"], "split-required")
|
||||
carried = json.loads((work / "carried-work.json").read_text(
|
||||
encoding="utf-8-sig",
|
||||
))
|
||||
self.assertEqual(carried["implementation"], "retained")
|
||||
self.assertEqual(carried["owned_dirty_paths"], ["tracked.txt"])
|
||||
self.assertEqual((source / "tracked.txt").read_text(), "carried\n")
|
||||
|
||||
def test_carried_work_snapshot_seals_owned_submodule_changes(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
source, slot, work, config = source_repo_with_task(root)
|
||||
nested = source / "nested"
|
||||
git_repo(nested)
|
||||
(nested / "owned.txt").write_text("base\n", encoding="utf-8")
|
||||
git(nested, "add", "owned.txt")
|
||||
git(nested, "commit", "-m", "Create nested baseline")
|
||||
nested_head = git(nested, "rev-parse", "HEAD")
|
||||
git(
|
||||
source,
|
||||
"update-index",
|
||||
"--add",
|
||||
"--cacheinfo",
|
||||
f"160000,{nested_head},nested",
|
||||
)
|
||||
git(source, "commit", "-m", "Track nested repository")
|
||||
(work / "owned-paths.txt").write_text(
|
||||
"nested/owned.txt\n", encoding="utf-8",
|
||||
)
|
||||
(nested / "owned.txt").write_text("carried\n", encoding="utf-8")
|
||||
|
||||
snapshot = workspace.source_worktree_snapshot(
|
||||
config, slot, TASK_ID,
|
||||
)
|
||||
|
||||
self.assertEqual(snapshot["owned_dirty_paths"], ["nested"])
|
||||
self.assertEqual(snapshot["outside_owned_paths"], [])
|
||||
self.assertNotEqual(snapshot["worktree_digest"], "0" * 64)
|
||||
|
||||
def test_split_publish_routes_and_starts_implementation_carrier(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
root = Path(temporary)
|
||||
config = inbox_worktrees(root)
|
||||
main = Path(config["ai_main"])
|
||||
slot = Path(config["slot_worktree"])
|
||||
source = root / "source"
|
||||
git_repo(source)
|
||||
(source / "Telegram" / "build").mkdir(parents=True)
|
||||
(source / "tracked.txt").write_text("base\n", encoding="utf-8")
|
||||
git(source, "add", "-A")
|
||||
git(source, "commit", "-m", "Create baseline")
|
||||
config["source_root"] = str(source)
|
||||
source_task = "2026/07/18/active-task"
|
||||
source_dir = main / "tasks" / source_task
|
||||
state_path = source_dir / "state.yaml"
|
||||
state_path.write_text(
|
||||
state_path.read_text(encoding="utf-8")
|
||||
.replace("status: todo", "status: split-required")
|
||||
.replace("claimed_by: null", "claimed_by: macbook-twork")
|
||||
.replace("claimed_at: null", "claimed_at: 2026-07-18T10:00:00+04:00")
|
||||
.replace("claim_order: null", "claim_order: 1")
|
||||
.replace("phase: null", "phase: split-required")
|
||||
.replace(
|
||||
"inbox_receipt:",
|
||||
"model: gpt-5.6-sol\ninbox_receipt:",
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
work = source_dir / "work"
|
||||
work.mkdir()
|
||||
(work / "owned-paths.txt").write_text(
|
||||
"tracked.txt\n", encoding="utf-8",
|
||||
)
|
||||
for name in ("base", "run"):
|
||||
git(
|
||||
source,
|
||||
"update-ref",
|
||||
workspace.source_task_ref(source_task, name),
|
||||
"HEAD",
|
||||
)
|
||||
(source / "tracked.txt").write_text("carried\n", encoding="utf-8")
|
||||
snapshot = workspace.source_worktree_snapshot(
|
||||
config, main, source_task,
|
||||
)
|
||||
(work / "carried-work.json").write_text(
|
||||
json.dumps({"implementation": "retained", **snapshot}) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
git(main, "add", f"tasks/{source_task}")
|
||||
git(main, "commit", "-m", f"Split-required {source_task}")
|
||||
git(slot, "merge", "--ff-only", "master")
|
||||
|
||||
replacements = [
|
||||
"2026/07/20/adopt-active-task-implementation",
|
||||
"2026/07/20/finish-active-task-integration",
|
||||
]
|
||||
receipt = "receipts/2026/07/20/split-active-task.md"
|
||||
for task_id in replacements:
|
||||
directory = slot / "tasks" / task_id
|
||||
directory.mkdir(parents=True)
|
||||
(directory / "task.md").write_text(
|
||||
f"# {task_id.rsplit('/', 1)[-1]}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(directory / "state.yaml").write_text(
|
||||
f"""status: todo
|
||||
type: implement
|
||||
created: 2026-07-20
|
||||
project: null
|
||||
depends_on: []
|
||||
claimed_by: null
|
||||
claimed_at: null
|
||||
claim_order: null
|
||||
lease_until: null
|
||||
phase: null
|
||||
inbox_receipt: {receipt}
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
receipt_path = slot / receipt
|
||||
receipt_path.parent.mkdir(parents=True)
|
||||
receipt_path.write_text(
|
||||
"\n".join([source_task, *replacements]) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
with mock.patch.object(
|
||||
workspace, "worktree_config", return_value=config,
|
||||
):
|
||||
result = run_command(
|
||||
workspace.command_split_publish,
|
||||
source_task=source_task,
|
||||
replacements=replacements,
|
||||
receipt=receipt,
|
||||
implementation_carrier=replacements[0],
|
||||
paths=[
|
||||
f"tasks/{source_task}",
|
||||
*(f"tasks/{task_id}" for task_id in replacements),
|
||||
receipt,
|
||||
],
|
||||
)
|
||||
self.assertEqual(result["status"], "split")
|
||||
self.assertTrue((main / "tasks" / source_task / "split.yaml").is_file())
|
||||
self.assertFalse((main / "tasks" / source_task / "state.yaml").exists())
|
||||
resolved = workspace.resolve_task(
|
||||
main, workspace.load_states(main), source_task,
|
||||
)
|
||||
self.assertEqual(resolved["status"], "split")
|
||||
self.assertEqual(resolved["split_into"], replacements)
|
||||
carrier = workspace.load_states(main)[replacements[0]]
|
||||
self.assertEqual(carrier["claimed_by"], "macbook-twork")
|
||||
self.assertEqual(carrier["carried_from"], source_task)
|
||||
self.assertEqual((source / "tracked.txt").read_text(), "carried\n")
|
||||
|
||||
with mock.patch.object(
|
||||
workspace, "worktree_config", return_value=config,
|
||||
):
|
||||
started = run_command(
|
||||
workspace.command_start,
|
||||
task=replacements[0],
|
||||
require=[],
|
||||
)
|
||||
self.assertEqual(started["status"], "in-progress")
|
||||
self.assertIsNotNone(workspace.resolved_ref(
|
||||
source,
|
||||
workspace.source_task_ref(replacements[0], "base"),
|
||||
))
|
||||
self.assertIsNone(workspace.resolved_ref(
|
||||
source,
|
||||
workspace.source_task_ref(source_task, "base"),
|
||||
))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -13,10 +13,10 @@ This file adapts harness mechanics and removes unnecessary text normalization.
|
||||
prompt containing exact repository, task, artifact, and input paths. Do not
|
||||
rely on the parent conversation being inherited.
|
||||
- Tell every disposable phase leaf Agent not to delegate and never to commit.
|
||||
Publication-owning orchestrators — `process-inbox`, `perform-task`, discovered
|
||||
routing, and pending-task consolidation — follow the shared workflow's exact
|
||||
helper, commit, and publication contract instead. Preserve its single-writer
|
||||
and one-stateful-performer constraints.
|
||||
Publication-owning orchestrators — `process-inbox`, `perform-task`, split
|
||||
routing, discovered routing, and pending-task consolidation — follow the
|
||||
shared workflow's exact helper, commit, and publication contract instead.
|
||||
Preserve its single-writer and one-stateful-performer constraints.
|
||||
- Every phase leaf and the performer inherit the parent model, as the shared
|
||||
workflow says. Do not pass a model override on the Agent call: its family
|
||||
aliases already resolve to the newest permitted model of that family, so an
|
||||
@@ -49,9 +49,9 @@ This file adapts harness mechanics and removes unnecessary text normalization.
|
||||
- If the first real leaf Agent is rejected before work begins because nested
|
||||
delegation is unavailable, use the shared same-session fallback. Do not
|
||||
treat mere presence of the Agent tool as a successful delegation probe.
|
||||
- Whenever an Agent is asked to run `process-inbox`, `perform-task`,
|
||||
discovered-task routing, or pending-task consolidation — the orchestrating
|
||||
roles — explicitly tell it to read this adapter completely before the
|
||||
- Whenever an Agent is asked to run `process-inbox`, `perform-task`, split-task
|
||||
routing, discovered-task routing, or pending-task consolidation — the
|
||||
orchestrating roles — explicitly tell it to read this adapter completely before the
|
||||
applicable shared skill or reference. Do NOT tell leaf phase agents to read
|
||||
this adapter: their phase prompts are self-contained and already carry the
|
||||
leaf rules (no delegation, no commits, progress and reply contracts); an
|
||||
|
||||
@@ -19,6 +19,14 @@ follow-up requires its affirmative independence test. Continue until that
|
||||
frozen-and-derived batch reaches the scheduler's normal stop condition or a
|
||||
global hard stop.
|
||||
|
||||
Apply the shared `split-required` result and routing phase. A performer publishes
|
||||
that state; this parent launches one fresh foreground split Agent that reads the
|
||||
complete shared split reference, creates and publishes the replacements, and
|
||||
retires the source task. Replace the source id in the frozen batch with those
|
||||
replacements. When retained implementation exists, start the checkout-owned
|
||||
carrier first so the helper transfers its sealed source state; do not reset or
|
||||
checkpoint that work.
|
||||
|
||||
Apply the shared source-lineage gate in this parent scheduler. Before batch
|
||||
freeze, a missing approved prerequisite pauses through `AskUserQuestion` after
|
||||
the exact branch and compatible-branch report. After freeze but before Phase 1,
|
||||
@@ -35,10 +43,10 @@ scheduler context, and require it to read the complete shared consolidation
|
||||
reference. Never run consolidation inside the performer or discovery-routing
|
||||
Agent, and defer it while the active task owns dirty local phase state.
|
||||
|
||||
Every inbox worker, performer, discovered-task routing Agent, and pending-task
|
||||
consolidation Agent must be told in its initial prompt to read
|
||||
`.claude/ai-workflow-adapter.md` completely before the applicable shared skill
|
||||
or reference. Use the Agent tool for those workers; do not start Claude
|
||||
Every inbox worker, performer, split-routing Agent, discovered-task routing
|
||||
Agent, and pending-task consolidation Agent must be told in its initial prompt
|
||||
to read `.claude/ai-workflow-adapter.md` completely before the applicable shared
|
||||
skill or reference. Use the Agent tool for those workers; do not start Claude
|
||||
subprocesses through Bash.
|
||||
|
||||
Arguments, when present, are natural-language hints for new shared work; their
|
||||
|
||||
@@ -11,6 +11,9 @@ the Claude adapter's delegation and text-handling substitutions. Resolve, start
|
||||
or resume, implement, verify, and publish only the named task. Do not
|
||||
continue with other queue work, route discoveries, or consolidate pending tasks
|
||||
afterward; those post-result phases belong to the `continue` scheduler.
|
||||
If assessment or review convergence proves the task intrinsically broad,
|
||||
publish the shared `split-required` result with retained source state and stop;
|
||||
do not create its replacement tasks in this command.
|
||||
|
||||
Apply the shared pipeline's conditional `[ai] ` commit-subject rule exactly;
|
||||
decide it per commit, require it only when all changes and the purpose are
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -45,6 +45,8 @@ stage
|
||||
/snap/gui/*.png
|
||||
/snap/gui/*.desktop
|
||||
/snap/plugins/__pycache__
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
/Telegram/*.user.*
|
||||
*.txt.user
|
||||
|
||||
@@ -32,9 +32,9 @@ resumability, and AI publication. This file adapts harness mechanics.
|
||||
consolidation, and phase leaves. Do not restrict `capability_mode`;
|
||||
those workers need shell plus writes.
|
||||
- Tell every disposable phase leaf not to delegate and never to commit.
|
||||
Publication-owning orchestrators — `process-inbox`, `perform-task`,
|
||||
discovered routing, and pending-task consolidation — follow the shared
|
||||
workflow's exact helper, commit, and publication contract. Preserve its
|
||||
Publication-owning orchestrators — `process-inbox`, `perform-task`, split
|
||||
routing, discovered routing, and pending-task consolidation — follow the
|
||||
shared workflow's exact helper, commit, and publication contract. Preserve its
|
||||
single-writer and one-stateful-performer constraints.
|
||||
- When a blocking call returns without its required artifact, retry that
|
||||
disposable worker once in a fresh `spawn_subagent` with more specific
|
||||
@@ -57,8 +57,8 @@ nested-delegation probe.
|
||||
This session is the scheduler only. Do not plan or implement Telegram
|
||||
changes here.
|
||||
|
||||
Spawn each inbox worker, performer, discovery-routing worker, and
|
||||
pending-task consolidation worker as a blocking `spawn_subagent`. Tell
|
||||
Spawn each inbox worker, performer, split-routing worker, discovery-routing
|
||||
worker, and pending-task consolidation worker as a blocking `spawn_subagent`. Tell
|
||||
every one of those workers, in its initial prompt, to read this adapter
|
||||
completely before the applicable shared skill or reference.
|
||||
|
||||
@@ -133,8 +133,9 @@ invocation resume it.
|
||||
|
||||
The only scheduler state that is not already on disk is the frozen batch
|
||||
(`invocation_mode`, `initial_batch_task_ids`, `batch_task_ids`,
|
||||
`discovered_task_ids`, `attempted_blocked`, consolidation records). After
|
||||
a compact, recover those lists from the compact summary and the last
|
||||
`discovered_task_ids`, `attempted_blocked`, consolidation records, and ordered
|
||||
split records with carrier ids). After a compact, recover those lists from the
|
||||
compact summary and the last
|
||||
scheduler notes. Do not take a fresh queue snapshot and freeze a new
|
||||
batch. A later queue id that was never in this invocation's batch stays
|
||||
out, exactly as the shared skill says.
|
||||
|
||||
@@ -21,6 +21,14 @@ until that frozen-and-derived batch reaches the scheduler's normal stop
|
||||
condition or a global hard stop. Do not stop on your own because a compact
|
||||
is approaching.
|
||||
|
||||
Apply the shared `split-required` result and routing phase. A performer publishes
|
||||
that state; this parent launches one fresh blocking split worker that reads the
|
||||
complete shared split reference, creates and publishes the replacements, and
|
||||
retires the source task. Replace the source id in the frozen batch with those
|
||||
replacements. When retained implementation exists, start the checkout-owned
|
||||
carrier first so the helper transfers its sealed source state; do not reset or
|
||||
checkpoint that work.
|
||||
|
||||
Apply the shared skill's pending-task consolidation phase too. At each
|
||||
eligible clean AI-slot boundary, recover an older `pending_consolidations`
|
||||
marker or consolidate newly routed tasks in one fresh blocking
|
||||
@@ -30,9 +38,9 @@ the complete shared consolidation reference. Never run consolidation inside
|
||||
the performer or discovery-routing worker, and defer it while the active
|
||||
task owns dirty local phase state.
|
||||
|
||||
Every inbox worker, performer, discovered-task routing worker, and
|
||||
pending-task consolidation worker must be told in its initial prompt to
|
||||
read `.grok/ai-workflow-adapter.md` completely before the applicable shared
|
||||
Every inbox worker, performer, split-routing worker, discovered-task routing
|
||||
worker, and pending-task consolidation worker must be told in its initial prompt
|
||||
to read `.grok/ai-workflow-adapter.md` completely before the applicable shared
|
||||
skill or reference. Use `spawn_subagent` with `background: false` for those
|
||||
workers. A continue-spawned performer is at depth 1 and must run every
|
||||
phase leaf as a same-session checklist. Do not start Grok subprocesses
|
||||
|
||||
@@ -12,6 +12,9 @@ substitutions. Resolve, start or resume, implement, verify, and publish only
|
||||
the named task. Do not continue with other queue work, route discoveries, or
|
||||
consolidate pending tasks afterward; those post-result phases belong to the
|
||||
`continue` scheduler.
|
||||
If assessment or review convergence proves the task intrinsically broad,
|
||||
publish the shared `split-required` result with retained source state and stop;
|
||||
do not create its replacement tasks in this command.
|
||||
|
||||
Apply the shared pipeline's conditional `[ai] ` commit-subject rule exactly;
|
||||
decide it per commit, require it only when all changes and the purpose are
|
||||
|
||||
Reference in New Issue
Block a user