Add stroke frame planning coverage
This commit is contained in:
@@ -17,6 +17,10 @@ a task is complex. The default is still one agent executing one task from
|
|||||||
- Avoid merge conflicts by giving every agent a disjoint task and file scope.
|
- Avoid merge conflicts by giving every agent a disjoint task and file scope.
|
||||||
- Keep teams rolling: when one team finishes, integrate or park its result and
|
- Keep teams rolling: when one team finishes, integrate or park its result and
|
||||||
start the next disjoint team without waiting for every other team to finish.
|
start the next disjoint team without waiting for every other team to finish.
|
||||||
|
- Prefer parallel execution whenever scopes are disjoint: run multiple teams at
|
||||||
|
once, and give each team 2 or 3 workers when the work can be split cleanly.
|
||||||
|
- Keep communication terse: no fillers, no cheerleading, no narrative padding.
|
||||||
|
Use direct technical wording only.
|
||||||
|
|
||||||
## Roles
|
## Roles
|
||||||
|
|
||||||
@@ -47,8 +51,8 @@ captain or worker whenever the scope can be made clear.
|
|||||||
|
|
||||||
### Team Captain
|
### Team Captain
|
||||||
|
|
||||||
Use `gpt-5.4` for each captain. A captain owns one coherent task group, for
|
Use `gpt-5.4` for each captain. A captain owns one coherent task group and is
|
||||||
example:
|
responsible for domain-level planning, for example:
|
||||||
|
|
||||||
- renderer/export boundary
|
- renderer/export boundary
|
||||||
- legacy adapter retirement
|
- legacy adapter retirement
|
||||||
@@ -60,13 +64,13 @@ example:
|
|||||||
The captain owns implementation for its assigned task group. A team should be a
|
The captain owns implementation for its assigned task group. A team should be a
|
||||||
captain plus multiple workers when the work can be split into disjoint files.
|
captain plus multiple workers when the work can be split into disjoint files.
|
||||||
The captain turns one task-group objective, or a small coherent run of adjacent
|
The captain turns one task-group objective, or a small coherent run of adjacent
|
||||||
task rows, into smaller disjoint subtasks, spawns or requests workers when
|
task rows, into 2 or 3 smaller disjoint subtasks when possible, spawns or
|
||||||
useful, reviews their changes, runs focused validation when cheap, and returns
|
requests workers when useful, reviews their changes, runs focused validation
|
||||||
an integration-ready result. If nested subagents are available, the captain may
|
when cheap, and returns an integration-ready result. If nested subagents are
|
||||||
spawn workers and continue through the next compatible subtask after each worker
|
available, the captain may spawn workers and continue through the next
|
||||||
returns. If nested subagents are not available in the current surface, the
|
compatible subtask after each worker returns. If nested subagents are not
|
||||||
captain returns a worker plan and the director performs the second-level spawns
|
available in the current surface, the captain returns a worker plan and the
|
||||||
without taking over implementation.
|
director performs the second-level spawns without taking over implementation.
|
||||||
|
|
||||||
The captain must not edit broad shared files unless assigned. The captain must
|
The captain must not edit broad shared files unless assigned. The captain must
|
||||||
not rewrite the task tracker or roadmap except for a requested status note.
|
not rewrite the task tracker or roadmap except for a requested status note.
|
||||||
@@ -81,13 +85,16 @@ Every worker and explorer must be told:
|
|||||||
- this repository may have other agents working in parallel
|
- this repository may have other agents working in parallel
|
||||||
- do not revert or overwrite unrelated changes
|
- do not revert or overwrite unrelated changes
|
||||||
- stay inside the assigned scope
|
- stay inside the assigned scope
|
||||||
|
- focus on the assigned task first; do not start by reading unrelated docs or
|
||||||
|
broad repository areas unless the task explicitly requires it
|
||||||
- report changed files, validation run, and blockers
|
- report changed files, validation run, and blockers
|
||||||
|
|
||||||
## Model Selection
|
## Model Selection
|
||||||
|
|
||||||
| Work Type | Model | Reasoning Effort | Use |
|
| Work Type | Model | Reasoning Effort | Use |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| Captain for a task group | `gpt-5.4` | `medium` default, `high` for renderer/platform architecture | Split task, supervise workers, summarize integration. |
|
| Director orchestration and integration | `gpt-5.4-mini` | `low` or `medium` | Scope selection, task routing, conflict checks, validation, docs/debt updates, commits, pushes. |
|
||||||
|
| Team captain for a domain slice | `gpt-5.4` | `medium` default, `high` for renderer/platform architecture | Split a broad domain slice into worker-sized tasks, supervise workers, review results, and integrate changes. |
|
||||||
| Risky implementation with cross-file C++ behavior | `gpt-5.4` | `medium` or `high` | Code changes touching contracts, build graph, or live adapters. |
|
| Risky implementation with cross-file C++ behavior | `gpt-5.4` | `medium` or `high` | Code changes touching contracts, build graph, or live adapters. |
|
||||||
| Bounded implementation in known files | `gpt-5.4-mini` | `medium` | Localized tests, simple adapters, docs/debt updates, small refactors. |
|
| Bounded implementation in known files | `gpt-5.4-mini` | `medium` | Localized tests, simple adapters, docs/debt updates, small refactors. |
|
||||||
| Fast lookup or inventory | `gpt-5.3-codex-spark` | `low` or `medium` | `rg` inventory, file ownership map, simple grep-based answers. |
|
| Fast lookup or inventory | `gpt-5.3-codex-spark` | `low` or `medium` | `rg` inventory, file ownership map, simple grep-based answers. |
|
||||||
@@ -96,7 +103,9 @@ Every worker and explorer must be told:
|
|||||||
|
|
||||||
Prefer the inherited model unless the user requested this director workflow or
|
Prefer the inherited model unless the user requested this director workflow or
|
||||||
there is a clear task-specific reason to override. In this workflow, the user
|
there is a clear task-specific reason to override. In this workflow, the user
|
||||||
has requested `gpt-5.4` captains, so use that override for captains.
|
has requested `gpt-5.4` team leads, so use that override for captains and keep
|
||||||
|
the director on `gpt-5.4-mini` for orchestration unless a higher-reasoning
|
||||||
|
escalation is justified.
|
||||||
|
|
||||||
## Token Discipline
|
## Token Discipline
|
||||||
|
|
||||||
@@ -112,10 +121,13 @@ has requested `gpt-5.4` captains, so use that override for captains.
|
|||||||
workers/captains unless the task truly needs more.
|
workers/captains unless the task truly needs more.
|
||||||
- Ask for compact final reports: changed files, result, validation, blockers,
|
- Ask for compact final reports: changed files, result, validation, blockers,
|
||||||
next recommendation.
|
next recommendation.
|
||||||
|
- Keep final reports minimal and technical.
|
||||||
- Close completed agents after their results are integrated or rejected.
|
- Close completed agents after their results are integrated or rejected.
|
||||||
- Prefer the smallest number of teams that keeps disjoint work moving. Multiple
|
- Prefer the smallest number of teams that keeps disjoint work moving. Multiple
|
||||||
captains are appropriate when task rows have non-overlapping write scopes and
|
captains are appropriate when task rows have non-overlapping write scopes and
|
||||||
can validate independently. Avoid many agents in one file family.
|
can validate independently. Avoid many agents in one file family, but do use
|
||||||
|
multiple teams when the scopes are disjoint and the work can advance in
|
||||||
|
parallel.
|
||||||
- Do not synchronize all teams at a barrier unless validation or merge risk
|
- Do not synchronize all teams at a barrier unless validation or merge risk
|
||||||
requires it. Use rolling integration: wait for whichever team finishes first,
|
requires it. Use rolling integration: wait for whichever team finishes first,
|
||||||
process that result, then immediately start another disjoint team if ready
|
process that result, then immediately start another disjoint team if ready
|
||||||
@@ -125,7 +137,9 @@ has requested `gpt-5.4` captains, so use that override for captains.
|
|||||||
|
|
||||||
1. Director picks two or more `Ready` tasks from
|
1. Director picks two or more `Ready` tasks from
|
||||||
`docs/modernization/tasks.md` with disjoint write scopes.
|
`docs/modernization/tasks.md` with disjoint write scopes.
|
||||||
2. Director assigns each independent task group to a `gpt-5.4` captain.
|
2. Director assigns each independent task group to a `gpt-5.4` captain, with
|
||||||
|
preference for 2 or 3 worker subtasks per team when the scope can be split
|
||||||
|
cleanly.
|
||||||
3. Captains implement directly or coordinate workers/explorers for disjoint
|
3. Captains implement directly or coordinate workers/explorers for disjoint
|
||||||
subtasks, and may continue through a coherent sequence of adjacent tasks
|
subtasks, and may continue through a coherent sequence of adjacent tasks
|
||||||
within the assigned scope.
|
within the assigned scope.
|
||||||
@@ -151,10 +165,11 @@ Validation: <COMMANDS>.
|
|||||||
|
|
||||||
Goal: <ONE PARAGRAPH>.
|
Goal: <ONE PARAGRAPH>.
|
||||||
|
|
||||||
Own this task group through implementation. Build a small team of workers for
|
Own this task group through planning and implementation. Build a small team of
|
||||||
disjoint subtasks when possible, review their outputs, and keep looping through
|
`gpt-5.4-mini` workers for disjoint subtasks when possible, review their
|
||||||
the assigned coherent task sequence until the scope is done, blocked, or no
|
outputs, and keep looping through the assigned coherent task sequence until the
|
||||||
longer safe to continue. Use gpt-5.4 only for risky C++ behavior changes. Keep
|
scope is done, blocked, or no longer safe to continue. Use `gpt-5.4` for broad
|
||||||
|
domain planning, interface decisions, and risky C++ behavior changes. Keep
|
||||||
tasks small enough to validate. Do not edit outside the assigned scope. Other
|
tasks small enough to validate. Do not edit outside the assigned scope. Other
|
||||||
agents may be working in parallel; do not revert unrelated changes.
|
agents may be working in parallel; do not revert unrelated changes.
|
||||||
|
|
||||||
@@ -179,6 +194,8 @@ Read scope: <FILES/DIRS>.
|
|||||||
Validation: <COMMANDS>.
|
Validation: <COMMANDS>.
|
||||||
|
|
||||||
Make the smallest behavior-preserving change that satisfies the done checks.
|
Make the smallest behavior-preserving change that satisfies the done checks.
|
||||||
|
Do not spend tokens on broad document review or inventory outside the assigned
|
||||||
|
scope unless the task requires it.
|
||||||
Update tests/docs only if listed. If the task is larger than expected, stop and
|
Update tests/docs only if listed. If the task is larger than expected, stop and
|
||||||
report the split instead of broadening scope.
|
report the split instead of broadening scope.
|
||||||
|
|
||||||
|
|||||||
@@ -605,6 +605,82 @@ void retained_stroke_frame_samples_with_dirty_tracking_updates_after_finish(pp::
|
|||||||
PP_EXPECT(h, nearly_equal(pass_dirty_boxes[4].w, 10.0F));
|
PP_EXPECT(h, nearly_equal(pass_dirty_boxes[4].w, 10.0F));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void retained_stroke_frame_planner_uses_previous_sample_and_projection_mode(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const auto frames = pp::panopainter::plan_legacy_canvas_stroke_frames(
|
||||||
|
pp::panopainter::LegacyCanvasStrokeComputeRequest {
|
||||||
|
.previous_sample = StrokeSample {
|
||||||
|
.col = { 0.25F, 0.5F, 0.75F },
|
||||||
|
.pos = { 10.0F, 20.0F, 0.0F },
|
||||||
|
.origin = { 0.0F, 0.0F, 0.0F },
|
||||||
|
.scale = { 1.0F, 1.0F },
|
||||||
|
.size = 4.0F,
|
||||||
|
.flow = 0.5F,
|
||||||
|
.opacity = 0.75F,
|
||||||
|
.angle = 0.0F,
|
||||||
|
},
|
||||||
|
.samples = std::array<StrokeSample, 2> {
|
||||||
|
StrokeSample {
|
||||||
|
.col = { 1.0F, 0.0F, 0.0F },
|
||||||
|
.pos = { 14.0F, 26.0F, 0.0F },
|
||||||
|
.origin = { 0.0F, 0.0F, 0.0F },
|
||||||
|
.scale = { 1.0F, 1.0F },
|
||||||
|
.size = 2.0F,
|
||||||
|
.flow = 0.6F,
|
||||||
|
.opacity = 0.7F,
|
||||||
|
.angle = 0.0F,
|
||||||
|
},
|
||||||
|
StrokeSample {
|
||||||
|
.col = { 0.0F, 1.0F, 0.0F },
|
||||||
|
.pos = { 18.0F, 30.0F, 2.0F },
|
||||||
|
.origin = { 0.0F, 0.0F, 0.0F },
|
||||||
|
.scale = { 1.0F, 1.0F },
|
||||||
|
.size = 6.0F,
|
||||||
|
.flow = 0.8F,
|
||||||
|
.opacity = 0.9F,
|
||||||
|
.angle = 0.0F,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.zoom = 1.0F,
|
||||||
|
.mixer_size = glm::vec2(64.0F, 64.0F),
|
||||||
|
.model_view = glm::mat4(1.0F),
|
||||||
|
},
|
||||||
|
[&](std::array<vertex_t, 4>& brush_quad, bool project_3d, glm::mat4 model_view) {
|
||||||
|
if (project_3d) {
|
||||||
|
PP_EXPECT(h, nearly_equal(model_view[0][0], 1.0F));
|
||||||
|
}
|
||||||
|
for (const auto& vertex : brush_quad) {
|
||||||
|
PP_EXPECT(h, !glm::any(glm::isnan(vertex.pos)));
|
||||||
|
}
|
||||||
|
return std::array<vertex_t, 4> { brush_quad };
|
||||||
|
},
|
||||||
|
[](glm::vec4 mixer_rect, glm::vec4 color, float flow, float opacity, auto&& shapes) {
|
||||||
|
return StrokeFrame {
|
||||||
|
.col = color,
|
||||||
|
.flow = flow,
|
||||||
|
.opacity = opacity,
|
||||||
|
.shapes = std::move(shapes),
|
||||||
|
.m_mixer_rect = mixer_rect,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
PP_EXPECT(h, frames.size() == 2U);
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[0].m_mixer_rect.x, 8.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[0].m_mixer_rect.y, 18.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[0].m_mixer_rect.z, 4.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[0].m_mixer_rect.w, 4.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[0].col.r, 1.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[0].flow, 0.6F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[0].opacity, 0.7F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[1].m_mixer_rect.x, 12.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[1].m_mixer_rect.y, 16.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[1].m_mixer_rect.z, 6.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[1].m_mixer_rect.w, 6.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[1].col.g, 1.0F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[1].flow, 0.8F));
|
||||||
|
PP_EXPECT(h, nearly_equal(frames[1].opacity, 0.9F));
|
||||||
|
}
|
||||||
|
|
||||||
void retained_stroke_live_pass_with_face_framebuffers_preserves_order_and_dirty_tracking(pp::tests::Harness& h)
|
void retained_stroke_live_pass_with_face_framebuffers_preserves_order_and_dirty_tracking(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
StrokeFrame frame;
|
StrokeFrame frame;
|
||||||
@@ -961,6 +1037,9 @@ int main()
|
|||||||
harness.run(
|
harness.run(
|
||||||
"retained_stroke_frame_samples_with_dirty_tracking_updates_after_finish",
|
"retained_stroke_frame_samples_with_dirty_tracking_updates_after_finish",
|
||||||
retained_stroke_frame_samples_with_dirty_tracking_updates_after_finish);
|
retained_stroke_frame_samples_with_dirty_tracking_updates_after_finish);
|
||||||
|
harness.run(
|
||||||
|
"retained_stroke_frame_planner_uses_previous_sample_and_projection_mode",
|
||||||
|
retained_stroke_frame_planner_uses_previous_sample_and_projection_mode);
|
||||||
harness.run(
|
harness.run(
|
||||||
"retained_stroke_live_pass_with_face_framebuffers_preserves_order_and_dirty_tracking",
|
"retained_stroke_live_pass_with_face_framebuffers_preserves_order_and_dirty_tracking",
|
||||||
retained_stroke_live_pass_with_face_framebuffers_preserves_order_and_dirty_tracking);
|
retained_stroke_live_pass_with_face_framebuffers_preserves_order_and_dirty_tracking);
|
||||||
|
|||||||
Reference in New Issue
Block a user