Skip to content

fix(bin): file sea chart kinds on the field the chart reads and report unplaceable members - #63

Merged
Freudator86 merged 8 commits into
mainfrom
fm/fm-sea-chart-kinds-nicht-speicherbar
Aug 4, 2026
Merged

fix(bin): file sea chart kinds on the field the chart reads and report unplaceable members#63
Freudator86 merged 8 commits into
mainfrom
fm/fm-sea-chart-kinds-nicht-speicherbar

Conversation

@Freudator86

Copy link
Copy Markdown
Owner

Intent

Make the sea chart able to show fog and course boundaries at all - today it can never show either, in principle rather than by accident. A real chart drew five members, four of them chart material, and reported fog: 0, out_of_course: 0 with no footnote.

Root cause, established by measurement rather than assumption: 'kind' names two DIFFERENT fields on a backlog row with opposite vocabularies. 'tasks-axi add --kind' is the RECORD kind, is open, and stores 'fog' and 'out-of-course' exactly as written. 'tasks-axi hold --kind' is a CLOSED set (captain, external, load, parked, future) that rejects both. The chart filters on the record kind (.kind). AGENTS.md section 10 gave the id markers and the hold but never the record kind, so a firstmate following the instruction literally filed records with no .kind at all and the filter matched nothing.

IMPORTANT CONTEXT A REVIEWER READING ONLY THE DIFF WOULD NOT KNOW: the originating investigation concluded that tasks-axi rejects BOTH kinds and that 'one of the two sides must give way'. That premise was wrong - it measured the hold command, not the add command. This was verified empirically before any code changed. The task brief explicitly settled that the repair is on OUR side and must NOT touch tasks-axi: it is a third-party AXI-suite package under node_modules that this repo does not own, and a local patch would be silently erased by the next suite update - the same failure shape being fixed. So no tasks-axi change was made, deliberately.

The brief also required that AGENTS.md section 10 become true in the SAME change, because the instruction was half the defect rather than a bystander to it: the next agent follows the instruction, not the code. Section 10 now names both commands and why they differ.

Second, independent half of the brief, required to stand on its own: a member carrying a kind the chart cannot recognise must produce a visible report rather than a silent zero, because an empty section reads as a claim about the course ('there is no fog here'). Added unplaced[] with a cause and a plain-language why per member, plus a count and summary rendering. The placed set is deliberately collected FROM the sections rather than from copies of their predicates, so a section added later that is not folded in produces a loud false row instead of another silent zero - this is a deliberate design choice favouring the recoverable direction, consistent with the rest of this script.

DELIBERATE SCOPE BOUNDARY, set by the brief and not an oversight: fm-seekarte-verfassen-wandert-in-den-render (the chart body being hand-written at render time with no record behind it) is a separate defect in the same file, queued behind this one. The render step was deliberately NOT restructured.

Also deliberate: the id markers -fog- and -oos- remain a separate spelling from the kind names, hardcoded in fm-sea-chart.sh. That split is pre-existing, documented in fm-chart-kinds-lib.sh, and owned by fm-sea-chart.sh's header - it is not a third spelling of the kinds and was intentionally left alone.

Verification performed: followed the corrected section 10 from a clean start with the fleet's real commands - both records store and both appear in their correct sections; a record deliberately given a misspelled kind is reported in unplaced[]; a mutation check confirmed the new tests fail when the report is silenced. Repo lint clean (pinned ShellCheck 0.11.0), changed-test run 58 suites 0 failures. Tests also pin the tasks-axi vocabularies themselves so a package update that moves either one fails loudly rather than silently emptying the chart again.

What Changed

  • AGENTS.md section 10 and bin/fm-chart-kinds-lib.sh now file fog and out-of-course on the record kind (tasks-axi add --kind), which is the field bin/fm-sea-chart.sh filters on, and keep it separate from the closed hold --kind vocabulary (captain, external, load, parked, future) that rejects both names — previously the instruction gave only the id markers and the hold, so records were filed with no .kind and the FOG and OUT OF COURSE sections could never match anything. No change was made to tasks-axi, a third-party AXI-suite package this repo does not own.
  • bin/fm-sea-chart.sh gained unplaced[] and misfiled[]: every member the chart counts but places in no section is named with a cause (no-kind, marker-kind-mismatch, decision-shape, blocked, held), a kind_defect rank that puts kind faults above ordinary held work, and a plain-language why; records whose -fog-/-oos- id marker disagrees with their record kind are reported with both spellings side by side and excluded from takeable[]. The placed set is collected from what the sections actually emit rather than from copies of their predicates, so a future section that is not folded in produces a loud row instead of a silent zero.
  • Reconciliation and counts were trued to match: inventory unpaired_variants[] are no longer treated as drawn and now surface in withheld[] as unpaired-variant, with a new counts.withheld_folded reconciling the folded/withheld overlap, and the summary headings, output contract, and .agents/skills/sea-chart/SKILL.md rendering instructions were reworded to stop claiming those records never reached the actionable surface. tests/fm-sea-chart.test.sh adds 558 lines pinning the storable fields of both tasks-axi vocabularies, the corrected section 10 instruction, and the unplaced/misfiled/ranking output; the Test phase reports 28 behavior tests with 0 failures plus two mutation checks that fail when the reports are silenced.

Risk Assessment

✅ Low: This round only reworps user-facing report headings, the output-contract comment, and the skill to remove claims a heading cannot verify, and adds a regression test that pins those headings as input-independent; the behavioral logic (misfiled detection, unplaced ranking, withheld reconciliation, per-record whys) is unchanged and every heading now asserts only what is true by construction of the list it heads.

Testing

Ran the targeted sea-chart suite (28 tests, 0 failures) plus the six neighbouring suites that consume the changed chart-kinds lib and AGENTS.md section 10 (0 failures), then verified the intent end-to-end the way a firstmate actually experiences it: I filed records in a scratch home with the real tasks-axi commands, first following the old section 10 literally and reproducing the exact defect against the base-commit script (5 members drawn, fog: 0, out_of_course: 0, no footnote), then running the changed script on that identical backlog to see both records named under UNPLACED with the missing record kind explained, and finally following the corrected section 10 from a clean start so FOG and OUT OF COURSE both render with their hold reasons, with a deliberately swapped record surfacing under MISFILED naming both spellings. The intent's corrected premise was re-measured live rather than taken on trust — hold --kind rejects both chart names with a VALIDATION_ERROR listing the closed set while add --kind stores them — and two mutations confirmed the new tests are load-bearing: silencing the reports fails them, and restoring the base-commit AGENTS.md fails the instruction test while the tasks-axi storable-field test keeps passing. The end-user surface here is a terminal CLI, so the evidence is command transcripts and rendered chart output rather than screenshots; there is no rendered UI, HTML, or browser surface in this change. The scratch home and repo copy were removed and the worktree is clean.

Evidence: Before/after: same backlog, base-commit chart vs this change, plus the corrected filing

--- BEFORE (base commit 8e8ae25) --- members: 5 rule: id is "voy" or begins with "voy-"; ... [no FOG section, no OUT OF COURSE section, no footnote - fog: 0, out_of_course: 0] --- AFTER (this change), same backlog --- members: 5 rule: ... of those, 2 could not be placed in any section - see UNPLACED (2 carrying a kind this chart cannot classify) UNPLACED - members this chart counted and drew in no section: KIND DEFECTS - the kind on these is missing, unrecognised, or at odds with the id: ? voy-fog-render-grain [kind: none, hold-kind: future] no kind is recorded on it, and every section of this chart places a member by its kind, so none of them can take it. File a dark patch on the course as kind fog, a deliberate boundary as kind out-of-course ... AGENTS.md section 10 has the commands. A hold kind is a different field and never places a record here. ? voy-oos-render-restructure [kind: none, hold-kind: future] ... --- AND, filed the way the CORRECTED section 10 says --- FOG: ~ render-grain: Is the render grain wrong or only the body? no measurement yet OUT OF COURSE - these never rise: x render-restructure: Restructuring the render step is a separate defect queued behind this one

SAME BACKLOG, TWO SCRIPTS - records filed the way the OLD section 10 said (hold --kind future only)

--- BEFORE (base commit 8e8ae25) ------------------------------------------
members: 5   rule: id is "voy" or begins with "voy-"; a longer undertaking sharing this prefix is drawn here too, which is the recoverable direction

TAKEABLE NOW:
   [no FOG section, no OUT OF COURSE section, no footnote - 5 members drawn, fog: 0, out_of_course: 0]

--- AFTER (this change) ---------------------------------------------------
members: 5   rule: id is "voy" or begins with "voy-"; a longer undertaking sharing this prefix is drawn here too, which is the recoverable direction
  of those, 2 could not be placed in any section - see UNPLACED (2 carrying a kind this chart cannot classify)

UNPLACED - members this chart counted and drew in no section:
  KIND DEFECTS - the kind on these is missing, unrecognised, or at odds with the id:
  ? voy-fog-render-grain  [kind: none, hold-kind: future]
      no kind is recorded on it, and every section of this chart places a member by its kind, so none of them can take it. File a dark patch on the course as kind fog, a deliberate boundary as kind out-of-course, and anything else as the kind of work it actually is; AGENTS.md section 10 has the commands. A hold kind is a different field and never places a record here.
  ? voy-oos-render-restructure  [kind: none, hold-kind: future]
      no kind is recorded on it, and every section of this chart places a member by its kind, so none of them can take it. File a dark patch on the course as kind fog, a deliberate boundary as kind out-of-course, and anything else as the kind of work it actually is; AGENTS.md section 10 has the commands. A hold kind is a different field and never places a record here.

TAKEABLE NOW:

AND, filed the way the CORRECTED section 10 says (add --kind fog / --kind out-of-course):
FOG:
  ~ render-grain: Is the render grain wrong or only the body?
      no measurement yet
  ~ voy-oos-markers-differ: The two spellings can disagree
      -

OUT OF COURSE - these never rise:
  x render-restructure: Restructuring the render step is a separate defect
      queued behind this one
Evidence: Chart rendered after filing with the corrected section 10 (FOG, OUT OF COURSE, MISFILED all on the page)

MISFILED - the id marker and the record kind of these members disagree: ! voy-oos-markers-differ [marker: -oos-, kind: fog, drawn under FOG] its id carries the -oos- marker, which files it under this chart as out-of-course, but its record kind is fog. Every section here places a member by its kind, so this record is drawn under FOG, and OUT OF COURSE is drawn without it. One of the two spellings is wrong and the chart cannot tell which: correct the kind to out-of-course, or rename the id if this record is not that. FOG: ~ render-grain: Is the render grain wrong or only the body? no measurement yet ~ voy-oos-markers-differ: The two spellings can disagree - OUT OF COURSE - these never rise: x render-restructure: Restructuring the render step is a separate defect queued behind this one

chart: voy
destination: Bring fog and course boundaries onto the sea chart   [read from the backlog record]

INCOMPLETENESS, computed fresh for this build:
  0 captain-gated records in the backlog for this chart
    of those, 0 reached the actionable surface -> 0 shown (0 folded away)
    not carried by any decision section: 0
  possibly already answered: 0

members: 5   rule: id is "voy" or begins with "voy-"; a longer undertaking sharing this prefix is drawn here too, which is the recoverable direction

MISFILED - the id marker and the record kind of these members disagree:
  ! voy-oos-markers-differ  [marker: -oos-, kind: fog, drawn under FOG]
      its id carries the -oos- marker, which files it under this chart as out-of-course, but its record kind is fog. Every section here places a member by its kind, so this record is drawn under FOG, and OUT OF COURSE is drawn without it. One of the two spellings is wrong and the chart cannot tell which: correct the kind to out-of-course, or rename the id if this record is not that.

TAKEABLE NOW:
  > voy-ship-lib
      unsupervised edit: true   landing: unknown
      a supervised worker branches from the tip, reviews it as first reader, and drives it commit by commit through the pipeline

FOG:
  ~ render-grain: Is the render grain wrong or only the body?
      no measurement yet
  ~ voy-oos-markers-differ: The two spellings can disagree
      -

OUT OF COURSE - these never rise:
  x render-restructure: Restructuring the render step is a separate defect
      queued behind this one
Evidence: tasks-axi transcript: the record kind stores both names, the hold kind rejects both

$ tasks-axi hold voy-fog-render-grain --reason "probe" --kind fog error: "--kind must be one of captain, external, load, parked, future" code: VALIDATION_ERROR [exit 2] $ tasks-axi hold voy-oos-render-restructure --reason "probe" --kind out-of-course error: "--kind must be one of captain, external, load, parked, future" code: VALIDATION_ERROR [exit 2] $ tasks-axi add voy-fog-render-grain "..." --kind fog ok: added voy-fog-render-grain (fog) -> Queued

$ tasks-axi add voy "Bring fog and course boundaries onto the sea chart" --kind ship
ok: added voy (ship) -> Queued
task:
  id: voy
  title: Bring fog and course boundaries onto the sea chart
  state: queued
  blocked: no
  blocked_by: none
  held: no
  hold_reason: "-"
  hold_kind: "-"
  hold_until: "-"
  kind: ship
  repo: "-"
  priority: "-"
  created: 2026-08-04
  closed: "-"
  deps: none
  links: none
  body: ""
help[2]:
  - Run `tasks-axi start voy` to move it to in flight
  - Run `tasks-axi block voy --by <other>` to record a dependency

# OLD section 10: "File both ... as <chart>-fog-<slug> and <chart>-oos-<slug> and hold them with --kind future"
$ tasks-axi add voy-fog-render-grain "Is the render grain wrong or only the body?"
ok: added voy-fog-render-grain -> Queued
task:
  id: voy-fog-render-grain
  title: Is the render grain wrong or only the body?
  state: queued
  blocked: no
  blocked_by: none
  held: no
  hold_reason: "-"
  hold_kind: "-"
  hold_until: "-"
  kind: task
  repo: "-"
  priority: "-"
  created: 2026-08-04
  closed: "-"
  deps: none
  links: none
  body: ""
help[2]:
  - Run `tasks-axi start voy-fog-render-grain` to move it to in flight
  - Run `tasks-axi block voy-fog-render-grain --by <other>` to record a dependency
$ tasks-axi hold voy-fog-render-grain --reason "no measurement yet" --kind future
ok: hold voy-fog-render-grain -> held (future)
task:
  id: voy-fog-render-grain
  title: Is the render grain wrong or only the body?
  state: queued
  blocked: no
  blocked_by: none
  held: yes
  hold_reason: no measurement yet
  hold_kind: future
  hold_until: "-"
  kind: task
  repo: "-"
  priority: "-"
  created: 2026-08-04
  closed: "-"
  deps: none
  links: none
  body: ""
help[2]:
  - Run `tasks-axi unhold voy-fog-render-grain` to resume dispatch
  - Run `tasks-axi ready --include-held` to review paused work

$ tasks-axi add voy-oos-render-restructure "Restructuring the render step is a separate defect"
ok: added voy-oos-render-restructure -> Queued
task:
  id: voy-oos-render-restructure
  title: Restructuring the render step is a separate defect
  state: queued
  blocked: no
  blocked_by: none
  held: no
  hold_reason: "-"
  hold_kind: "-"
  hold_until: "-"
  kind: task
  repo: "-"
  priority: "-"
  created: 2026-08-04
  closed: "-"
  deps: none
  links: none
  body: ""
help[2]:
  - Run `tasks-axi start voy-oos-render-restructure` to move it to in flight
  - Run `tasks-axi block voy-oos-render-restructure --by <other>` to record a dependency
$ tasks-axi hold voy-oos-render-restructure --reason "queued behind this one" --kind future
ok: hold voy-oos-render-restructure -> held (future)
task:
  id: voy-oos-render-restructure
  title: Restructuring the render step is a separate defect
  state: queued
  blocked: no
  blocked_by: none
  held: yes
  hold_reason: queued behind this one
  hold_kind: future
  hold_until: "-"
  kind: task
  repo: "-"
  priority: "-"
  created: 2026-08-04
  closed: "-"
  deps: none
  links: none
  body: ""
help[2]:
  - Run `tasks-axi unhold voy-oos-render-restructure` to resume dispatch
  - Run `tasks-axi ready --include-held` to review paused work

# the premise the original investigation drew from -- measured, not assumed:
$ tasks-axi hold voy-fog-render-grain --reason "probe" --kind fog
error: "--kind must be one of captain, external, load, parked, future"
code: VALIDATION_ERROR
[exit 2]
$ tasks-axi hold voy-oos-render-restructure --reason "probe" --kind out-of-course
error: "--kind must be one of captain, external, load, parked, future"
code: VALIDATION_ERROR
[exit 2]

# two ordinary members so the chart really does draw five
$ tasks-axi add voy-ship-lib "Own the two spellings in one lib" --kind ship
ok: added voy-ship-lib (ship) -> Queued
task:
  id: voy-ship-lib
  title: Own the two spellings in one lib
  state: queued
  blocked: no
  blocked_by: none
  held: no
  hold_reason: "-"
  hold_kind: "-"
  hold_until: "-"
  kind: ship
  repo: "-"
  priority: "-"
  created: 2026-08-04
  closed: "-"
  deps: none
  links: none
  body: ""
help[2]:
  - Run `tasks-axi start voy-ship-lib` to move it to in flight
  - Run `tasks-axi block voy-ship-lib --by <other>` to record a dependency
$ tasks-axi add voy-ship-tests "Pin the storage contract" --kind ship
ok: added voy-ship-tests (ship) -> Queued
task:
  id: voy-ship-tests
  title: Pin the storage contract
  state: queued
  blocked: no
  blocked_by: none
  held: no
  hold_reason: "-"
  hold_kind: "-"
  hold_until: "-"
  kind: ship
  repo: "-"
  priority: "-"
  created: 2026-08-04
  closed: "-"
  deps: none
  links: none
  body: ""
help[2]:
  - Run `tasks-axi start voy-ship-tests` to move it to in flight
  - Run `tasks-axi block voy-ship-tests --by <other>` to record a dependency
Evidence: Backlog rows written by the real commands under the corrected instruction

- [ ] voy-fog-render-grain - Is the render grain wrong or only the body? (kind: fog) (since 2026-08-04) (hold: no measurement yet) (hold-kind: future) - [ ] voy-oos-render-restructure - Restructuring the render step is a separate defect (kind: out-of-course) (since 2026-08-04) (hold: queued behind this one, ...) (hold-kind: future)

# Backlog

## In flight

## Queued
- [ ] voy - Bring fog and course boundaries onto the sea chart (kind: ship) (since 2026-08-04)

- [ ] voy-fog-render-grain - Is the render grain wrong or only the body? (kind: fog) (since 2026-08-04) (hold: no measurement yet) (hold-kind: future)
- [ ] voy-oos-render-restructure - Restructuring the render step is a separate defect (kind: out-of-course) (since 2026-08-04) (hold: queued behind this one, as fm-seekarte-verfassen-wandert-in-den-render) (hold-kind: future)
- [ ] voy-oos-markers-differ - The two spellings can disagree (kind: fog) (since 2026-08-04)
- [ ] voy-ship-lib - Own the two spellings in one lib (kind: ship) (since 2026-08-04)
## Done
Evidence: Mutation checks: silencing the report and un-fixing the instruction both fail the new tests

MUTATION A - emit unplaced[] and misfiled[] as empty arrays (report silenced): not ok - each unplaceable member must be named by id MUTATION B - restore the base-commit AGENTS.md section 10 (instruction un-fixed): ok - the chart kinds store on the record kind, and the hold kind still refuses them not ok - section 10 must file fog on the RECORD kind: it is the only field the chart classifies by, and naming only the hold is what made both sections permanently empty

MUTATION A - emit unplaced[] and misfiled[] as empty arrays (report silenced):
not ok - each unplaceable member must be named by id

MUTATION B - restore the base-commit AGENTS.md section 10 (instruction un-fixed):
ok - the chart kinds store on the record kind, and the hold kind still refuses them
not ok - section 10 must file fog on the RECORD kind: it is the only field the chart classifies by, and naming only the hold is what made both sections permanently empty
Evidence: Base-commit chart JSON on the same backlog: fog 0, out_of_course 0, 5 members

{ "members": 5, "fog": 0, "out_of_course": 0, "counts": { "records_in_backlog": 0, "records": 0, "decisions": 0, "folded": 0, "withheld": 0, "possibly_answered": 0 } }

$ base-commit bin/fm-sea-chart.sh voy --json | jq "{members, fog: (.fog|length), out_of_course: (.out_of_course|length), counts}"
{
  "members": 5,
  "fog": 0,
  "out_of_course": 0,
  "counts": {
    "records_in_backlog": 0,
    "records": 0,
    "decisions": 0,
    "folded": 0,
    "withheld": 0,
    "possibly_answered": 0
  }
}

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 4 issues found → auto-fixed (5) ✅
  • ⚠️ bin/fm-sea-chart.sh:505 - The new $placed set folds in $seen, which (line 419) includes unpaired_variants[] ids from fm-decision-inventory.sh:180-184. Those records are emitted in NO chart section: the chart only outputs decisions: $open_decisions (line 418) plus each decision's key-matched variants; unpaired_variants appears nowhere else in fm-sea-chart.sh. Concrete path: chart voy with voy-panel-judge-decision-k1 and voy-panel-a-decision-k2, both open kind captain; the -a record's key is not in $authkeys, so it becomes an unpaired variant, enters $seen, is therefore excluded from $withheld (line 436) and now also from $unplaced (line 510) - while still raising counts.records and counts.folded. The result is exactly the invisible-member class this change exists against, and it contradicts the chart's own limits[] (line 557) and SKILL.md:106-107 ("Every folded record stays visible... a question only an analyst raised must be discoverable by eye rather than silently absent"). Earliest shared boundary: derive $placed from what the chart actually emits ($open_decisions ids plus their variants ids) instead of $seen, or emit unpaired_variants in the chart output. Pre-existing invisibility, but the new net encodes the wrong boundary and the author's stated design was to collect the placed set FROM the sections.
  • ℹ️ bin/fm-sea-chart.sh:478 - A member with a missing or misspelled record kind that carries no hold and no unresolved blocker passes every takeable predicate ($chart_kinds | index(null) is null, kind != captain, dkey null) and renders under "TAKEABLE NOW" with an unsupervised-edit pair, instead of reaching unplaced[]. Path: tasks-axi add voy-fog-retention &#34;...&#34; with no --kind (the original defect) where the follow-up hold is forgotten or fails - the fog marker is then advertised as work to pick up rather than reported. The new fixture (tests/fm-sea-chart.test.sh:424-425) only covers the variant that carries a hold, so this path is untested. Flagged, not prescribed: the id-marker/kind split that would detect it (marker(), line 306) is declared deliberately out of scope in the intent.
  • ℹ️ bin/fm-sea-chart.sh:388 - The blocked and held causes put every open non-chart-kind member with a hold or unresolved blocker into unplaced[] permanently. On a real chart with ordinary kind: ship rows held as parked/external/load, the UNPLACED block - headed "members on this course the chart could not place, so the sections below are missing them" - renders one multi-line paragraph each, ahead of WITHHELD and ahead of the actual kind defects the section was built to surface. Factually accurate (the chart has no section for held ordinary work) but it dilutes the signal; the new test fixture contains no held ordinary work, so the breadth is not exercised. Whether that breadth is intended, or whether held/blocked ordinary work belongs on a quieter line, is the author's call.
  • ℹ️ AGENTS.md:480 - The new filing instruction reads tasks-axi add &lt;id&gt; &#34;&lt;title&gt;&#34; --kind fog|out-of-course. Copied literally into a shell - which is how the previous half of this defect happened - bash treats | as a pipeline: the record is created with kind fog and a boundary lands in FOG instead of OUT OF COURSE, with only a "command not found" on stderr. Suggest spelling the alternation in prose (--kind fog for a dark patch, --kind out-of-course for a boundary); tests/fm-sea-chart.test.sh:399 pins this exact string, so the assertion would move with it.

🔧 Fix: place unpaired variants, unkinded work, and rank kind defects
2 issues (1 warning, 1 info) still open:

  • ⚠️ bin/fm-sea-chart.sh:629 - The incompleteness block still prints "withheld from the actionable surface: N", but the new unpaired-variant cause (line 348-351) is by construction a record that DID reach the actionable surface - the fold dropped it afterwards. On the new fixture the page reads "of those, 2 reached the actionable surface -> 1 shown (1 folded away)" and then "withheld from the actionable surface: 1", while the same record is printed below under the reworded heading "WITHHELD - open captain-gated records no decision section of this chart carries" with a why beginning "it reached the actionable surface". The record is also counted in both folded and withheld with nothing on the page reconciling that. The output contract (line 150) and the WITHHELD heading (line 657) were both reworded for precisely this reason in the same commit; this one line was missed. Suggest matching them, e.g. "not carried by any decision section: N".
  • ℹ️ bin/fm-sea-chart.sh:516 - Informational, no action requested. The takeable filter now excludes .kind == null as instructed, but a member with a MISSPELLED chart kind and no hold and no blocker (e.g. --kind out-of-cours, follow-up hold forgotten) still passes every takeable predicate and renders under TAKEABLE NOW while OUT OF COURSE reads empty. This is the remainder of the round-1 finding after the user scoped the fix to .kind == null; separating a typo from an ordinary non-chart kind (ship, docs, scout are all legitimately takeable) needs the -fog-/-oos- id marker cross-checked against the kind, and the intent states that split "was intentionally left alone". Recorded so the residual path is visible rather than presumed closed.

🔧 Fix: true withheld label and report marker-kind mismatches
2 warnings still open:

  • ⚠️ .agents/skills/sea-chart/SKILL.md:90 - The script's incompleteness label was corrected this commit (bin/fm-sea-chart.sh:671, now "not carried by any decision section: N (M of them folded away above rather than never returned)"), but the rendering instruction the chart body is actually written from still says "how many were withheld from the actionable surface". That is the same false claim for the unpaired-variant cause, and it contradicts SKILL.md:98 four lines further down ("the one the surface did return and the fold then dropped"), which the previous commit added. An agent following section 90 on the new unpaired-variant fixture renders "withheld from the actionable surface: 1" directly above a record whose printed why begins "it reached the actionable surface". The new counts.withheld_folded is also not mentioned anywhere in the skill, so the rendered chart keeps the unreconciled folded/withheld double count that --summary now explains. Align line 90 with the script's wording and instruct the renderer to print withheld_folded; the intent itself treats the instruction as half the defect rather than a bystander to it.
  • ⚠️ bin/fm-sea-chart.sh:364 - marker_kind_mismatch detects the swapped case, but its only consumers are the takeable filter (line 542) and unplaced_reason - and unplaced[] is evaluated only for members no section placed. A record filed as voy-oos-tracker with --kind fog (the two commands in AGENTS.md section 10 differ only in the kind word) matches the fog filter at line 494, so it is in $placed, its mismatch result is discarded, and it renders under FOG with patch falling back to the whole id while OUT OF COURSE reads 0. That is the intent's headline harm - an empty section reading as a claim about the course - on the one input the new cross-check can see and does not report. The takeable exclusion does not reach it because such a record was never takeable. Note unplaced[] is the wrong home by its own definition (members drawn in no section), so the fitting boundary is the fog[]/out_of_course[] row itself carrying the mismatch, or a separate count, rather than widening unplaced.

🔧 Fix: report swapped chart kinds and true the skill label
1 info still open:

  • ℹ️ bin/fm-sea-chart.sh:380 - drawn_section only recognises the fog and out-of-course filters, so a misfiled record of kind captain gets drawn_in: null and the else-branch why at line 575: "no section drew it at all and the unplaced report names it too". Both clauses are false for that record - a captain record is drawn in decisions[] (via $seen) or in withheld[], which places it, so unplaced[] at line 601 never carries it and a reader sent to the unplaced report will not find it. Reachable via an open captain record whose id contains a chart marker between dashes, e.g. voy-fog-of-war-a-decision-scope. Every other misfiled class is truthful: an ordinary kind carrying a marker is excluded from takeable[] at line 597 and so really is in unplaced[]. Local fix: add a captain branch to drawn_section (e.g. "the decision sections"), or make the "unplaced report names it too" clause conditional on the record actually being unplaced rather than on drawn_section alone.

🔧 Fix: look up where misfiled records are actually drawn
1 warning still open:

  • ⚠️ bin/fm-sea-chart.sh:770 - The per-row why gained $named_is_empty (line 645) this commit because "the section it names renders zero" is false when that section is drawn with a different record - but the MISFILED summary heading above those rows still asserts it unconditionally: "the id and the record kind of these members disagree, so a section below is empty that should not be". On the double-swap fixture added two rounds ago (tests/fm-sea-chart.test.sh:620-625: voy-oos-tracker filed kind fog, voy-fog-retention filed kind out-of-course) FOG and OUT OF COURSE each carry one row, so nothing below is empty, and the rows themselves say so with "is drawn without it" while the heading says the opposite. The identical unconditional claim also survives in the output contract at lines 176-178 ("the section its id names renders zero and reads as a claim about the course"). Fix by hedging the heading to cover both cases, or by deriving it from whether any misfiled row actually has an empty named section, which the rows already compute. This is the last sentence in the misfiled/unplaced why sweep that is false for a reachable input class; every other branch I traced is true for every record that can reach it.

🔧 Fix: strip unverifiable claims from report headings and whys
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • bin/fm-test-run.sh tests/fm-sea-chart.test.sh — 28 behavior tests, 0 failures, including the new storable-field, instruction, unplaced, misfiled and ranking tests
  • bin/fm-test-run.sh tests/fm-instruction-owners.test.sh tests/fm-decision-inventory.test.sh tests/fm-bearings-snapshot.test.sh tests/fm-to-backlog.test.sh tests/fm-fleet-snapshot-view.test.sh tests/fm-backlog-lint.test.sh — the suites that consume the changed chart-kinds lib and AGENTS.md section 10; 6 suites, 0 failures
  • Manual e2e, old instruction: real tasks-axi add &lt;id&gt; &#34;&lt;title&gt;&#34; + tasks-axi hold &lt;id&gt; --reason ... --kind future in a scratch home, producing backlog rows with no (kind: ...)
  • Manual e2e, premise re-measured: tasks-axi hold voy-fog-render-grain --reason probe --kind fog and --kind out-of-course → both VALIDATION_ERROR: --kind must be one of captain, external, load, parked, future
  • Manual e2e, before: base-commit bin/fm-sea-chart.sh voy --summary and --json on that backlog → 5 members, fog: 0, out_of_course: 0, no FOG/OUT OF COURSE section, no footnote
  • Manual e2e, after on the same backlog: bin/fm-sea-chart.sh voy --summaryUNPLACED / KIND DEFECTS naming both records and the missing record kind
  • Manual e2e, corrected instruction: tasks-axi add &lt;id&gt; &#34;&lt;title&gt;&#34; --kind fog / --kind out-of-course + hold --kind future exactly as AGENTS.md:480-481 now says, then bin/fm-sea-chart.sh voy --summary → FOG and OUT OF COURSE both render with their hold reasons
  • Manual e2e, swap case: a -oos- id filed --kind fog → reported under MISFILED with marker, kind, drawn under FOG, and OUT OF COURSE named as drawn without it
  • Mutation A: emit unplaced: [] / misfiled: [] in a repo copy → not ok - each unplaceable member must be named by id
  • Mutation B: restore base-commit AGENTS.md and bin/fm-sea-chart.sh in a repo copy → the section 10 instruction test fails while the tasks-axi storable-field test still passes
⚠️ **Document** - 1 info
  • ℹ️ docs/sea-chart-provenance.md:108 - docs/sea-chart-provenance.md still says "Three incompleteness numbers - ours entirely" (line 108) and describes takeable[] as derived purely by subtraction (line 144), both of which the new counts and the new no-kind/marker-mismatch exclusions have moved past. Left unchanged on purpose: that document is an explicitly pinned comparison ("Our side | .agents/skills/sea-chart/SKILL.md and bin/fm-sea-chart.sh at 8872ddf"), so its statements are historically scoped to that commit rather than live claims, and rewriting them would silently re-date the Wayfinder comparison the MIT-licence notice rests on. Flagging as a judgment call in case the fleet wants the pin refreshed as separate work.
🔧 **Lint** - 1 issue found → auto-fixed ✅
  • ⚠️ linter found issues (exit code 1)

🔧 Fix: iterate misfiled whys one row per line
✅ Re-checked - no issues remain.

✅ **Push** - passed

✅ No issues found.

Coditan-XO added 8 commits August 3, 2026 20:38
…d report members it cannot place

The sea chart could never show fog or a course boundary, in principle rather
than by accident: a real chart drew five members, four of them chart material,
and reported `fog: 0  out_of_course: 0` with no footnote anywhere.

"kind" names two different fields on a backlog row, with opposite vocabularies.
`tasks-axi add --kind` is the RECORD kind, it is open, and it stores `fog` and
`out-of-course` exactly as written; `tasks-axi hold --kind` is a closed set
(captain, external, load, parked, future) that rejects both. The chart filters
on the record kind. AGENTS.md section 10 gave the id markers and the hold but
never the record kind, so a firstmate following it exactly filed records with no
`.kind` at all and the filter matched nothing. The instruction was half the
defect rather than a bystander to it, because the next agent follows the
instruction and not the code.

The repair is one-sided. tasks-axi is a third-party AXI-suite package this repo
does not own, and a local patch to its vocabulary would be erased by the next
suite update - silently, which is the same failure shape being fixed here. So
section 10 now names both commands and says why they differ, and
fm-chart-kinds-lib.sh records which of the two fields each name belongs to.

Second, independent half: a member carrying a kind the chart cannot recognise is
now named in `unplaced[]` with the cause that left it out, rather than
disappearing behind an empty section. An empty section reads as a claim about
the course - "there is no fog here" - so a silent zero is worse than an error,
and this is what would have caught the defect on day one instead of at first
real use. The placed set is collected from the sections themselves rather than
from copies of their predicates, so a later section that is not folded in shows
up as a loud false row instead of another silent zero.

Verified by following the corrected instruction from a clean start: both records
store, both appear in their correct sections, and a record deliberately given a
misspelled kind is reported. The storable-field test pins the tasks-axi
vocabularies so a package update that moves either one fails rather than
silently emptying the chart again.
@Freudator86
Freudator86 merged commit cfb89ae into main Aug 4, 2026
10 checks passed
@Freudator86
Freudator86 deleted the fm/fm-sea-chart-kinds-nicht-speicherbar branch August 4, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant