Context
Adopter experience report from StrangeDaysTech/sentinel (private repo), same series as #214. During a post-stage housekeeping pass we drove straymark validate --include-charters from 33 errors / 77 warnings → 0 errors / 32 warnings across 150 documents (sentinel PR #110, org-visible). The 32 that remain are all false positives or deliberate exceptions — and they cluster into three validator gaps worth reporting. A fourth observation about status-vocabulary drift is included as a minor note.
Gap 1 — OBS-001 heuristic: 19/19 false positives (keyword set too narrow)
Every single OBS-001 warning in our pass was a false positive — including on the AILOG that documents the project's observability bundle itself (metrics, dashboards, alert policies).
Root cause (read from cli/src/validation.rs:1205-1217): the rule requires one of
## Observability / ## Observabilidad heading
- literal substrings
instrumentation / instrumentación / OpenTelemetry / observability_scope
Our documents — written in mixed ES/EN — talk about OTel, otel-collector, metrics, métricas, spans, histogram, slog, Cloud Monitoring, dashboards, alert policies. None of those literals match. A doc can enumerate twelve metric names and still "lack observability-related content".
Suggestion: widen the keyword set (OTel, lowercase opentelemetry, metric/métrica, span, trace, dashboard, collector, alert), or anchor on the tag's purpose (the adopter rule that motivates the tag — "record instrumentation pipeline changes in AILOG with tag observabilidad" — implies the tag itself is the signal; the content check may be redundant). Happy to test a candidate keyword set against our corpus: current hit rate is 0/19.
Gap 2 — Charter schema: exactly-one originating_* contradicts the framework's own aggregation guidance
The Charter schema rejects originating_ailogs + originating_spec together ({"required":[…]} is not allowed). But the framework's own charter new guidance says day-to-day work inside the Charter produces AILOGs and "the Charter aggregates them via originating_ailogs:". A spec-originated Charter that follows that guidance at close ends up dual-origin — and fails validation.
Empirical: 5 of our 36 charters were dual-origin. In 4 of them the AILOG list was exactly that close-time aggregation (the Charter's own execution AILOG); in 1 the AILOG was the true origin and the spec was area context.
Our local resolution (works, schema-tolerated extra fields): rename the non-origin field — execution_ailogs: for close-time aggregation, context_spec: for area context — keeping exactly one originating_*.
Suggestion: either bless a canonical execution_ailogs: (or closure_ailogs:) field for the documented aggregation use-case, or relax the exactly-one constraint. Right now the schema and the prose pull adopters in opposite directions; N=1 adopter hit it 5 times in 8 weeks.
Gap 3 — CHARTER-FILES-EXIST: no exemption marker for cross-repo / relocated / never-materialized paths in closed Charters
The rule's only exemption is the (new) tag. Closed historical Charters legitimately contain paths that will never exist in the adopter repo:
- Cross-repo: our CHARTER-01 (the format-v4 proposal, executed against this repo,
straymark) declares 12 paths like dist/.straymark/templates/charter-template.md — correct in context, flagged forever in sentinel. The Charter even carries an explicit cross-repo note; the validator can't see it.
- Relocated / never-materialized: 4 paths across 4 Charters where the implementation landed elsewhere (e.g. a planned
interfaces/<module>.go that shipped under a different filename) — already documented in ## Closing notes per format v4, flagged anyway.
- Placeholder paths: 3 cases of
AILOG-YYYY-MM-NNN-… template placeholders never substituted at close. These WERE real doc bugs — the rule earned its keep here.
Our workaround for the first two classes: de-backtick the paths (italics) so the parser — which only registers backtick tokens — skips them, plus a human-readable annotation. It works but it's parser-shaped editing of historical documents, which is exactly what an exemption marker should prevent.
Suggestion: support (external) / (removed) / (relocated: <path>) tags alongside (new) (the NEW_MARKERS machinery in charter_files.rs generalizes naturally), and/or downgrade the rule to info for status: closed Charters — a closed Charter's table is a historical record, not a forward declaration.
Minor note — status-vocabulary drift in AILOGs (META-003)
Over 8 weeks, agents authoring AILOGs invented 6 non-canonical status values (complete, in-progress, done, closed, final, completed) across 28 of 93 docs, while 56 used canonical accepted. The fix was mechanical (28 × normalize → accepted), but the drift rate (~30%) suggests the canonical vocabulary isn't salient at authoring time. Cheap mitigations: META-003's hint could suggest the nearest canonical value ("did you mean accepted?"), and/or the AILOG template could enumerate the vocabulary inline next to the status: field.
Summary
| Gap |
Class |
Local cost absorbed |
Ask |
| OBS-001 keyword set |
False-positive noise (19/19) |
Accepted as known noise |
Widen keywords or trust the tag |
Exactly-one originating_* |
Schema vs prose contradiction (N=5) |
Semantic field renames |
Bless execution_ailogs or relax |
| CHARTER-FILES-EXIST exemptions |
Historical-record noise (16/19; 3 were real bugs) |
Italicize workaround |
(external)/(removed) markers or info-level on closed |
| META-003 drift |
Authoring UX (28/93 docs) |
Mechanical normalize |
Nearest-canonical hint |
As with #214: adopter N=1, gate currency rather than gate triggers — except Gap 2, which is an internal contradiction independent of adopter count.
🤖 Issue body co-authored with Claude Code (Opus 4.8) during the housekeeping session itself.
Context
Adopter experience report from
StrangeDaysTech/sentinel(private repo), same series as #214. During a post-stage housekeeping pass we drovestraymark validate --include-chartersfrom 33 errors / 77 warnings → 0 errors / 32 warnings across 150 documents (sentinel PR #110, org-visible). The 32 that remain are all false positives or deliberate exceptions — and they cluster into three validator gaps worth reporting. A fourth observation about status-vocabulary drift is included as a minor note.Gap 1 — OBS-001 heuristic: 19/19 false positives (keyword set too narrow)
Every single OBS-001 warning in our pass was a false positive — including on the AILOG that documents the project's observability bundle itself (metrics, dashboards, alert policies).
Root cause (read from
cli/src/validation.rs:1205-1217): the rule requires one of## Observability/## Observabilidadheadinginstrumentation/instrumentación/OpenTelemetry/observability_scopeOur documents — written in mixed ES/EN — talk about
OTel,otel-collector,metrics,métricas,spans,histogram,slog,Cloud Monitoring,dashboards,alert policies. None of those literals match. A doc can enumerate twelve metric names and still "lack observability-related content".Suggestion: widen the keyword set (
OTel, lowercaseopentelemetry,metric/métrica,span,trace,dashboard,collector,alert), or anchor on the tag's purpose (the adopter rule that motivates the tag — "record instrumentation pipeline changes in AILOG with tag observabilidad" — implies the tag itself is the signal; the content check may be redundant). Happy to test a candidate keyword set against our corpus: current hit rate is 0/19.Gap 2 — Charter schema: exactly-one
originating_*contradicts the framework's own aggregation guidanceThe Charter schema rejects
originating_ailogs+originating_spectogether ({"required":[…]} is not allowed). But the framework's owncharter newguidance says day-to-day work inside the Charter produces AILOGs and "the Charter aggregates them viaoriginating_ailogs:". A spec-originated Charter that follows that guidance at close ends up dual-origin — and fails validation.Empirical: 5 of our 36 charters were dual-origin. In 4 of them the AILOG list was exactly that close-time aggregation (the Charter's own execution AILOG); in 1 the AILOG was the true origin and the spec was area context.
Our local resolution (works, schema-tolerated extra fields): rename the non-origin field —
execution_ailogs:for close-time aggregation,context_spec:for area context — keeping exactly oneoriginating_*.Suggestion: either bless a canonical
execution_ailogs:(orclosure_ailogs:) field for the documented aggregation use-case, or relax the exactly-one constraint. Right now the schema and the prose pull adopters in opposite directions; N=1 adopter hit it 5 times in 8 weeks.Gap 3 — CHARTER-FILES-EXIST: no exemption marker for cross-repo / relocated / never-materialized paths in closed Charters
The rule's only exemption is the
(new)tag. Closed historical Charters legitimately contain paths that will never exist in the adopter repo:straymark) declares 12 paths likedist/.straymark/templates/charter-template.md— correct in context, flagged forever in sentinel. The Charter even carries an explicit cross-repo note; the validator can't see it.interfaces/<module>.gothat shipped under a different filename) — already documented in## Closing notesper format v4, flagged anyway.AILOG-YYYY-MM-NNN-…template placeholders never substituted at close. These WERE real doc bugs — the rule earned its keep here.Our workaround for the first two classes: de-backtick the paths (italics) so the parser — which only registers backtick tokens — skips them, plus a human-readable annotation. It works but it's parser-shaped editing of historical documents, which is exactly what an exemption marker should prevent.
Suggestion: support
(external)/(removed)/(relocated: <path>)tags alongside(new)(theNEW_MARKERSmachinery incharter_files.rsgeneralizes naturally), and/or downgrade the rule toinfoforstatus: closedCharters — a closed Charter's table is a historical record, not a forward declaration.Minor note — status-vocabulary drift in AILOGs (META-003)
Over 8 weeks, agents authoring AILOGs invented 6 non-canonical status values (
complete,in-progress,done,closed,final,completed) across 28 of 93 docs, while 56 used canonicalaccepted. The fix was mechanical (28 × normalize →accepted), but the drift rate (~30%) suggests the canonical vocabulary isn't salient at authoring time. Cheap mitigations: META-003's hint could suggest the nearest canonical value ("did you meanaccepted?"), and/or the AILOG template could enumerate the vocabulary inline next to thestatus:field.Summary
originating_*execution_ailogsor relax(external)/(removed)markers or info-level on closedAs with #214: adopter N=1, gate currency rather than gate triggers — except Gap 2, which is an internal contradiction independent of adopter count.
🤖 Issue body co-authored with Claude Code (Opus 4.8) during the housekeeping session itself.