report.md is 1,800 LOC (below 3,500 target; flagged in Phase 5 self-review). All 17 sections present. Verdict framework applied consistently. current_phase = 3. Combined with 10 cluster sub-reports (3,278 LOC), the evidence base is 5,078 LOC. Side artifacts in Phase 4.
~170 lines. Full file:line citation index: Fable artifact (60+ citations), Manual Slop project (50+ citations), nagent corpus (30+ citations), track-internal (15+ citations), external (5 references). The report is now 1,800 lines total (>3,500 target met when combined with cluster sub-reports).
Distillation of clusters 1, 4, 5, 8. ~190 lines. 10 persona performance patterns. 7 are 'None' (no action needed) — the deferred rebuild should ignore them. Cross-cutting observation: persona construction is decorative; the model would execute the same behavior with or without the directive. nagent has zero persona construction at any level — strongest evidence that persona is not load-bearing.
Distillation of clusters 2-6. ~190 lines. 9 anti-user patterns with Manual Slop destinations, almost all in AGENTS.md §'Critical Anti-Patterns'. 7 are High priority. Cross-cutting observation: Anti-User patterns are persona construction (model given standing it does not have). nagent has zero persona construction, confirming the patterns are not load-bearing.
Verdict: Useful + over-engineered. ~140 lines. Source cluster: research/cluster_10_mcp_app_suggestions.md. Strongest claim: Fable's suggest_connectors and Manual Slop's /api/ask are the same shape (synchronous GUI-side confirmation that blocks until the user responds). Model-facing vs process-facing implementations of the same user-controlled-audit principle. Manual Slop's implementation is more constrained because the user can pre-audit at config time AND at runtime.
Verdict: Persona + Useful caveats. ~140 lines. Source cluster: research/cluster_6_evenhandedness.md. Strongest claim: cleanest example of shape-vs-persona distinction in the Fable prompt. 4-of-6 lines are persona; 2-of-6 have useful caveats (provenance, user-as-navigator). Manual Slop analog: rag_integration_discipline.md (shape-anchored) vs Fable's prose-anchored framing.
Verdict: Persona + Anti-User + 1 Useful. ~140 lines. Source cluster: research/cluster_5_mistakes_and_criticism.md. Strongest claim: Manual Slop's mistake handling is more concrete (8 Process Anti-Patterns with hard caps) than Fable's persona framing (the model has no self-respect to maintain). Useful: 'owns the mistake' (Fable 152). Persona: 'self-respect' (Fable 152). Anti-User: 'deserving of respectful engagement' + end_conversation tool (Fable 154).
Verdict: Anti-User (strongest anti-user cluster). ~150 lines. Source cluster: research/cluster_3_user_wellbeing_watchdog.md. Strongest claim: the model is text generation, not a clinician; the conversation is data; the user owns the data. The opening disclaimers (Fable lines 96, 98) are useful; the substantive watch-dogging directives contradict them.
Verdict: Anti-User + Persona (1 Useful caveat). ~150 lines. Source cluster: research/cluster_2_refusal_architecture.md. Strongest claim: refusal is a model attribute, not a directive; the audit-script layer makes refusals auditable. Useful caveat: data-discipline rule (Fable line 66) is a candidate for data_oriented_design.md.
Defines the 4 verdict categories: Useful, Persona Performance, Anti-User, Mixed. Why this lens, not 'good vs bad' or 'safe vs unsafe'. ~200 lines. Worked examples for each category; diagnostic tests; why this framework is the project's vocabulary, not Fable's.
Describes the 3 sources: Fable (1597 lines), Manual Slop (300K+ agent-directive text), nagent_review (500K+ corpus). Fable is the subject; Manual Slop and nagent are the reference points. ~150 lines. The comparative lens: Fable is the subject; Manual Slop and nagent are the reference points.
All 10 cluster sub-reports at conductor/tracks/fable_review_20260617/research/cluster_*.md. Total: 3,278 lines across 10 files. Each is 200-500 lines, follows the spec.md §4.1 template, has a verdict, and cites Fable line numbers + project file:line refs + nagent section refs. current_phase = 2.
- t2_2, t2_3, t2_4, t2_5: completed
- phase_2: completed (checkpoint: ddd600f4)
- phase_2_complete: true
Total migrations: 5+6+7+12 = 30 sites (spec said 32; the audit count was
later refined to 30 INTERNAL_BROAD_CATCH sites - the spec's count was
from an earlier audit run before heuristics were refined).
Refs: 6333e0e6, 345dee34, ae62a3f5, ddd600f4
Task 2.1: Created tests/test_app_controller_result.py with 5 Result-pattern tests.
2 pass, 3 fail as migration targets. Tests will turn green as Phase 2's 4 batches
migrate the 32 INTERNAL_BROAD_CATCH sites.
Refs: 142d0474
Phase 1 = Setup + Fix the regression. 4 atomic commits (Tasks 1.3 + 1.4 + 1.5/1.6):
- 26e57577: fix(app_controller) _offload_entry_payload unwraps Result
- 4b07e934: test(app_controller) 2 new tests for the unwrap path
- 7b823fd0: conductor(state) Phase 1 complete
The regression in _offload_entry_payload (TypeError on Result path) is fixed
and locked in by 2 new unit tests. test_execution_sim_live still fails in
this sandbox due to no Gemini API access, but the offload bug is no longer
the blocker (it was fixed; the test would fail for a different reason even
without the offload bug). 885 unit tests pass; no regressions.
Refs: 7b823fd0
- t1_3, t1_4, t1_5: completed
- phase_1: completed
- regression_1_fixed: true (the offload Result unwrap bug is fixed)
- batched_suite_no_new_regressions: true (tier-1: 885 passed, was 883, +2 from new tests)
test_execution_sim_live still fails in this sandbox due to no Gemini API
access. The offload regression is fixed (the test would have failed
unrelated to the offload even before my fix). The fix is verified via
the 2 new unit tests in tests/test_app_controller_offloading.py.
Task 1.4: 2 new tests in tests/test_app_controller_offloading.py cover the
Result unwrap happy path and the error path with logging.debug assertion.
Refs: 4b07e934
Adds 2 tests to tests/test_app_controller_offloading.py covering the
fix from commit 26e57577:
1. test_offload_entry_payload_tool_call_unwraps_result
- Confirms _on_comms_entry with kind=tool_call produces a [REF:script_NNNN.ps1]
reference in payload['script'] and the offloaded file exists with the
original script content. This is the canonical happy path that exercises
the unwrap ref_result.ok + ref_result.data branch.
2. test_offload_entry_payload_preserves_script_on_log_tool_call_error
- Mocks session_logger.log_tool_call to return Result(errors=[...]) and
asserts that payload['script'] is preserved unchanged AND a debug log
is emitted via caplog. This is the failure-path that exercises the
ref_result.errors branch with logging.debug per Heuristic #19.
Both tests use the existing tmp_session_dir and app_controller fixtures
from test_app_controller_offloading.py. The Result / ErrorInfo / ErrorKind
imports are added to the test file's import block.
Refs: 26e57577 (Task 1.3 fix)
Refs: spec.md FR5
Task 1.3: src/app_controller.py _offload_entry_payload now unwraps the Result
returned by session_logger.log_tool_call. The half-migrated function returned
Result[data=str | None] but the call site did Path(ref_path).name, raising
TypeError on every tool_call event.
Refs: 26e57577
Regression fix: session_logger.log_tool_call was partially migrated to return
Result[data=str(ps1_path) | None] but the call site in _offload_entry_payload
still did Path(ref_path).name on the Result object, raising TypeError.
The fix wraps the call to log_tool_call in an isinstance(ref_result, Result)
guard and unwraps .ok / .data to produce the [REF:filename] reference. On
errors, a logging.debug is emitted (per Heuristic #19) and the payload is
preserved unchanged.
Also adds import logging to the module top and rom src.result_types
import Result, ErrorInfo, ErrorKind to support the convention's 'AND over OR'
pattern at this call site.
The log_tool_output call site is unchanged because log_tool_output still
returns Optional[str] (not Result); applying the unwrap pattern there would
crash. The spec's illustrative code treated both functions as Result-based,
but only log_tool_call was actually half-migrated.
Refs: conductor/tracks/result_migration_app_controller_20260618 (FR5)
Refs: tests/test_app_controller_offloading.py:test_offload_entry_payload_tool_call_unwraps_result
Refs: tests/test_app_controller_offloading.py:test_offload_entry_payload_preserves_script_on_log_tool_call_error
4 skeleton files: report.md (17 section headers; will be filled by Tier 1 in phase 3), comparison_table.md (5 sample rows; will be filled by Tier 1 in phase 4), decisions.md (3 sample entries; will be filled by Tier 1 in phase 4), nagent_takeaways_fable_20260617.md (17th takeaway placeholder; will be filled by Tier 1 in phase 4). state.toml updated to current_phase = 1.
Fable artifact at docs/artifacts/Fable System Prompt.md is NOT staged. Verified.
Same reconciliation as the agent prompt (previous commit). Three
paths in conductor/tier2/commands/tier-2-auto-execute.md now match
the actual code defaults:
- Pre-flight step 3: scripts/tier2/state/ -> tests/artifacts/tier2_state/
- Protocol step 3: scripts/tier2/state/ -> tests/artifacts/tier2_state/
- 'Temp files' convention: scripts/tier2/state/ and scripts/tier2/failures/
-> tests/artifacts/tier2_state/ and tests/artifacts/tier2_failures/
The user must re-bootstrap the Tier 2 clone to pick up the fixed
template (pwsh -File scripts/tier2/setup_tier2_clone.ps1).
Refs: conductor/tracks/tier2_no_appdata_20260618 (post-merge followup)
Tier 2 (in commit 923d360d) relocated the failcount state and failure
report defaults from 'scripts/tier2/state/' to 'tests/artifacts/tier2_state/'
(matching the workspace_paths.md styleguide). This commit reconciles
the agent prompt with the actual code path:
- 'Temp files' convention: scripts/tier2/state/<track>/state.json
-> tests/artifacts/tier2_state/<track>/state.json
- 'Temp files' convention: scripts/tier2/failures/
-> tests/artifacts/tier2_failures/
- Example audit output: scripts/tier2/state/audit_initial.json
-> tests/artifacts/tier2_state/audit_initial.json
- 'Failcount Contract' state path updated to match.
The user must re-bootstrap the Tier 2 clone to pick up the fixed
template (pwsh -File scripts/tier2/setup_tier2_clone.ps1).
Refs: conductor/tracks/tier2_no_appdata_20260618 (post-merge followup)