Tasks: the checkout declares where its specs are
Phase 3 of 3 (requirements → design → tasks). A DAG of implementation tasks derived from the approved design. MUST be reviewed/approved before implementation begins.
Task list
TDD invariant (tdd.mode: standard): T1 writes the failing tests first. They cannot pass while GraphLinkConfig.spec_dir defaults to docs/specs, because that default is precisely what makes the repository's value unreachable — so the red is the defect itself, observed.
[x] 1. The failing tests. Extend
cli/tests/test_graphlink.pywith the unit cases from the design's testing strategy (repo value honoured, no-config default, CLI override, unset default, one resolution, event record, containment, foreign-checkout read) andcli/tests/test_graphlink_integration.pywith the two end-to-end cases (two repositories with differentspecDir;graph-state.jsonunder the repository's own directory). Update the_build_runtimestubs to the new arity.- Depends on: none
- Requirements: R1.1–R1.5, R2.1, R2.2, R3.1, R3.3, R4.1–R4.3
- Test:
uv run --project cli python -m pytest cli/tests/test_graphlink.py cli/tests/test_graphlink_integration.py— red: the repository'sspecDiris never honoured
[x] 2.
harness_config.spec_dir. AddDEFAULT_SPEC_DIRandspec_dir(harness)tocli/the_loop/harness_config.py; pointgraph/bootstrap.py::build_runtimeat it and split its docstring's justification sospec_rootandauthorized_usersare each explained by their own provenance.- Depends on: none
- Requirements: R1.2, R2.1
- Test:
test_harness_config.pyandtest_graph_*.pygreen, unmodified
[x] 3. The default change and the single resolution.
GraphLinkConfig.spec_dirdefaults to"";from_mappingreadsstr(data.get("specDir") or "");GraphLink._spec_dir+_is_contained;_build_runtimetakes the resolved value;_guardedresolves once and threads it into both the gate and the runtime.- Depends on: 1, 2
- Requirements: R1.1–R1.5, R2.1, R2.2, R4.3
- Test: T1's resolution/override/containment cases green
[x] 4. Prove ownership before reading the checkout. Move
_checkout_belongs_toahead of the spec-directory gate in_guarded; reword its warning, which can no longer name a spec directory.- Depends on: 3
- Requirements: R4.1, R4.2
- Test:
test_a_foreign_checkouts_harness_config_is_never_readgreen; the existing A6 cases (test_a_checkout_of_another_repo_is_never_coupledand friends) still pass
[x] 5.
graph.skipped. Register the type ineventlog.EVENT_TYPESand emit it from the two refusing gates withwork_item,action,reason,spec_dir.- Depends on: 3, 4
- Requirements: R3.1, R3.2, R3.3
- Test: T1's event-log case green;
test_every_emitted_event_type_is_documentedgreen
[x] 6. Config surface + docs.
.the-loop/cli-config.schema.json(routing.graph.specDirdefault""+ corrected description),skills/the-loop/templates/cli-config.yaml(no default-overriding value),docs/config/cli/routing-options.md(documented as an override; Type/Default block kept for the parity test).- Depends on: 3
- Requirements: R5.1, R5.2, R5.3
- Test:
make validateVALID;test_docs_parity.pygreen;markdownlintgreen
[x] 7. Capability docs + decision trail.
docs/capabilities/process-graph.mdanddocs/capabilities/webhook-triggers.md: where the daemon takes the spec directory from, the new skip record, and an issue-123 history row each.- Depends on: 3, 5
- Requirements: R5.4
- Test:
markdownlintgreen
[x] 8. Full gate.
make check(ruff, ruff format, pyright, markdownlint, validate_config, pytest) anduv run the-loop check issue-123 --recompute.- Depends on: 1–7
- Requirements: all
- Test: all green; evidence recorded in
execution-log.md
DAG
flowchart LR
T1[1 · failing tests] --> T3[3 · default + single resolution]
T2[2 · harness_config.spec_dir] --> T3
T3 --> T4[4 · ownership before read]
T3 --> T6[6 · config surface + docs]
T3 --> T5[5 · graph.skipped]
T4 --> T5
T3 --> T7[7 · capability docs]
T5 --> T7
T4 --> T8[8 · full gate]
T6 --> T8
T7 --> T8Non-goals
- Changing how
the-loop check/the-loop graphresolveworkflow.specDir— they already read it from the checkout, which is the behaviour this work item brings the daemon into line with. - Adding a per-repository map to
cli-config.yaml. Decision-044 rejected exactly that shape; the fix is to stop needing one. - Recording an event for every skip path. Only the two that are otherwise invisible emit (design C6).