-
New skills/work-graph-node-review/SKILL.md documents the methodology for judging a self-planned Work Graph node's output (real structured content vs. narrative prose standing in for it) -- distilled from the real narrative-output incident (docs/todo/validator-test-script-narrative- output-issue.md §6) and the conditional-not-assertive phrasing lesson already applied in _NARRATION_RETRY_HINT. Scoped explicitly against planner-output-review (Planner's fixed doc chain, task-level gate), qa-task-validation (overall task acceptance), and skill-defect-remediation (rewriting a Skill file itself) -- this one judges a single self-planned node's output, nothing broader. Wired into roles/planner_reviewer, roles/coder, roles/validator role.json skills lists. .claude/agents/*.md left untouched -- that's a deploy-time artifact compiled from role.json by agent_profile.deploy_agent_definitions(), not hand-synced (confirmed stale already: coder.md is missing an even earlier Phase 2a skill addition). This completes Phase 2c (§2.1/§2.2/§6/§7.1 all implemented; §7.2's analysis was completed earlier without needing a code change). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Implements org-graph-unification-phase2-universal-self-planning-design.md §4 + §5, the engine-extension sub-phase (Phase 2a) -- no org-flow callers changed yet, this is the underlying capability. - _run_one_node() now resolves subagent_type/skill_ref per-node (node.get with the run-level org_node/skill_id as fallback), threaded through _ensure_node_row/_make_run_fn/_resolve_node_verify_fn -- a node's own judgment.kind="llm" call runs under its own declared identity, not always the graph-level default. Found and fixed a real gap surfaced by writing this: run_graph() only ensures the run-level default skill_id exists as a placeholder skill (work_node_execution.skill_ref's FK target) -- a node declaring its own skill_ref needs the same guarantee or the first INSERT for that skill_id fails FOREIGN KEY constraint. - New on_fail.action="dynamic_loop_back": Reflection-review (_judge_root_cause_node) runs three real parallel perspectives (content/ connectivity/history) under the Validator identity, each picking a target_node_id from the failing node's real ancestors plus a defect_kind (content_error vs skill_defect), majority-voted by _tally_reflection (own small Counter-based implementation, not imported from root_cause_trace.py -- that module already imports this one). A runtime ancestor check in _run_one_node backs up _tally_reflection's own degradation guarantee. - skill_defect triggers Fix-Skill (_fix_skill_for_node) before the loop back fires: reads the target node's declared skill_ref, builds a rewrite prompt from what was asked/produced/why it failed/prior loop history, runs it under the Validator identity (user-confirmed via AskUserQuestion), then calls the existing but -- until now -- never actually invoked by any production path bug_record.create_bug_record() + skill_update.update_skill(), against skill_query._REPO_ROOT (never target_folder_path). Logs a real 'skill_iterated' execution_event (a CHECK-enum value that has existed since the original U-001 schema but was never written before). Rate-limited to _MAX_SKILL_FIXES_PER_RUN_PER_SKILL rewrites of the same Skill per run. - New total-attempts-per-source-node loop_limit guard alongside the existing per-(target,source) one -- dynamic_loop_back can pick a different target each round, which would otherwise dodge the per-pair cap indefinitely. New settings_config key shape "{org_node}:{source_node_id}:total", no interface change needed there. - New skills/skill-defect-remediation/SKILL.md (Validator-only), wired into roles/validator/role.json. python3 -m unittest discover -s src (741 tests) + discover -s supervisor -p "test_*.py" (126 tests) both green, zero regressions. Deferred to Phase 2b (per design doc's own sequencing note): §2.1/§2.2 (work_graph_run.org_node removal + ux_work_graph_run_active index narrowing) -- narrowing that index now, before the append-to-existing-run mechanism lands, would break the current production flow, since Planner's and Coder's work_graph_run rows both stay non-terminal indefinitely on the happy path today (only Validator's own graph ever reaches 'done'). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Inserts Planner -> planner_reviewer -> Coder -> Validator into the fixed Org Graph flow (was Planner -> Coder -> Validator), per docs/todo/org-graph-unification-phase1-review-gate-design.md. A new planner_reviewer role independently judges whether Planner's BRD/PRD/SDD/ Benchmark output is real structured content (not narrative prose) before Coder is allowed to start, with a 3-attempt retry loop and a narration heuristic informed by the real narrative-output incident (docs/todo/validator-test-script-narrative-output-issue.md). Also fixes, in the same code path: - The P0 bug in task-execution-resume-assumes-planner-artifacts-exist.md: resuming a task no longer assumes sdd/prd/benchmark artifacts exist -- falls through to real replanning when they don't. - A fresh-run KeyError (not resume-specific) when a self-planned graph omits the prd/benchmark node types. - agent_profile.migrated_from_profile was NOT NULL, which broke as soon as a role with no legacy Hermes profile (planner_reviewer) was recorded. org_node_lifecycle._REQUIRED_ARTIFACTS["coder"] is narrowed from (brd,prd,sdd,benchmark) to (sdd,) -- the old 4-artifact gate never actually blocked anything since artifact_write.py sets validation_status='passed' unconditionally; planner_reviewer is the first real semantic gate. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Implements docs/todo/role-package-abstraction-design.md. Requirements review (docs/todo/graph-engineering-open-items.md's H section) had already corrected the requirements doc's own dependency analysis before this; scope confirmed with user 2026-08-06: relax all 4 org_node CHECK constraints in one pass, not staged. Format is JSON, not YAML: 05 §5.7's pure-stdlib constraint rules out PyYAML, and unlike Skill files (whose YAML frontmatter only Claude Code itself ever parses, never this codebase's own Python), role.json genuinely needs to be read by agent_profile.py -- json.load is the zero-risk choice over a hand-rolled parser. role.json is a REFERENCE manifest, not a content copy: identity.soul_md_path/ agents_md_path still point at the untouched agents/<role>/SOUL.md/AGENTS.md files. This is what makes "deployed output must stay identical" close to automatic -- render_agent_definition()'s body-assembly logic doesn't change at all, only the frontmatter's data source does (hardcoded FRONTMATTER dict -> parsed role.json). Verified byte-for-byte: diffed the old (git HEAD) render_agent_definition() output against the new one for all three roles, zero differences. agent_profile.py: ORG_NODES is now discovered by scanning roles/ for role.json files (_discover_role_ids()) instead of a hardcoded 3-tuple; FRONTMATTER/_DESCRIPTIONS/_MIGRATED_FROM_PROFILE dicts are gone. Every public function takes an optional roles_dir override specifically so a test can prove "a new role needs zero code changes" against a throwaway fixture directory (NewRoleWithoutCodeChangeTest) rather than asserting it by inspection. schema.py: skill.owner_org_node/task.assigned_org_node/work_graph_run.org_node/ agent_profile.org_node relaxed from CHECK(x IN ('planner','coder','validator')) to CHECK(x != ''). Real blast radius found during design (bigger than the requirements doc's own risk note): task/work_graph_run/skill are referenced by several other tables' foreign keys, but since only the parent tables' own CHECK text changes (child FK definitions are untouched), only these 4 parent tables need rebuilding -- followed SQLite's documented procedure for schema changes under active foreign keys (foreign_keys=OFF for the duration, rebuild, foreign_key_check to confirm nothing went dangling, foreign_keys=ON). migrate_relax_org_node_constraints() depends on D's migrate_add_work_graph_fork_columns() having run (called unconditionally, idempotent) so work_graph_run's rebuild has the right column set either way. ux_work_graph_run_active and task's 3 indexes verified to survive the rebuild. work_graph_run_query.py's own separately-hardcoded _VALID_ORG_NODES (a real dependency the requirements doc's risk section missed) now reuses agent_profile.ORG_NODES instead of maintaining a second copy. Explicitly NOT done (scoped out during requirements review, not an oversight): frontend/app.js's 4 hardcoded 3-role spots (route regex, sort order, dropdown, lookup object) -- a new role still won't be recognized by the PH3 console. A `role` table with real FK referential integrity was also not built; this uses the simpler "just relax the enum" approach. Full src suite (623 tests) + supervisor suite (125 tests) pass with zero regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>