You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
the narrative skills that did not exist — linkedin, x, and one shared
two-axis statement every platform skill cites (#462, part B) — the two
channels that shipped post.md/posting.yaml with no SKILL.md are exactly
the two whose narrative a session overwrote “for consistency”. They now carry
one — reader, angle, how it deliberately differs from github-readme, the whole
channel flow, and contract pointers (every limit cited from posting.yaml,
never re-typed). The two-axis rule (skills/FACTS-VS-NARRATIVE.md) has ONE
home; every platform skill links it, and no skill's own golden rule may
contradict it (order is narrative, not a fact), so the norm cannot drift
between skills; skills/README.md records that SKILL.md is required. pasco refine's task template names the target platform's skill as
the source of its reader/angle and states that a variant must not restate
another platform's headline, bio or body.
«facts are unique · narrative is per surface» — the norm and its advisory
check (#462, SPEC §21.8) — the rule lived only in one platform skill (as a
golden rule) and as a product goal, so a workspace could unify one headline
across its GitHub README, LinkedIn and X “for consistency” and pasco check
stayed green. SPEC §21.8 now states it normatively: every FACT in content/*.yaml (including identity.definition) is one and identical across
surfaces and a contradiction is a defect, not an adaptation, while the
per-platform headlines/bios rows are the narrative text; narrative
(reader, emphasis, order, subset via selection.views, composition via the
variant body) is per surface and is never propagated. pasco check gains the advisory text/same-across-platforms — a warn naming both platforms and the text
kind when two different platforms carry a byte-identical headline or a bio
in the same length band; exempt: the same platform across langs and identity.definition. No schema change, no hard gate. The skills half
(linkedin/xSKILL.md + the shared two-axis statement) lands in the
chained PR.
per-view selection.views.<v>.orderKeys — the narrative order the featured
sort was missing (#458, SPEC §21.2/§21.3) — github-readme's featured list is
fully derived (status rank → skill weight → name), so a workspace that wanted
"these two first" for one surface had only false claims (change status) or
invisible tiebreak tuning (change skills[].keywords); the measured case kept
the order as hand-edited text, outside the engine. A view now declares orderKeys by §19.2 key: the listed entries render first, in declared order, per block; the remaining entries keep the renderer's comparator. It is
workspace policy, never an SSOT field — order is narrative and two surfaces may
legitimately disagree. The pinning rule lives once in core (pinnedRanks),
used by the slice and by the sorting adapters through orderedForSurface; pasco status --selection prints the resolved order. A non-string key is a
config error in .pascorc and a warn at the pure core seam; a key the view does
not emit warns (selection/order-key-unknown) instead of no-op'ing silently.
No orderKeys ⇒ byte-identical artifact and report.
doctor --contract-delta — the upgrade names the fields, not only the
versions (#439, SPEC §7.6) — doctor reported engine 0.4.0 · schema v1.16 · requires engine >= 0.4.0 (met) and never WHAT changed between the two: a real
0.3.0 → 0.3.7 upgrade (contract v1.9 → v1.15) moved six adoptable fields, and
finding them took a supervision session across the CHANGELOG, the schema description and the geo report. pasco init now writes a "contract" floor
into .pascorc at birth — beside the #434"engine" floor, from the same
generated PROFILE_SCHEMA_VERSION, never a literal — and doctor --contract-delta diffs that floor against the installed contract: one entry per
minor with the fields it added and the surface that reads them, in five states
(delta · none · absent with the remedy · INVALID · ahead). --json
adds data.contractDelta only when the flag is passed, rows of exactly { version, fields, buys }. The exit matrix is unchanged: the floor DECLARES
and is never enforced (v1), so doctor reports without inventing a verdict the
gate does not back. The rows are a projection of the schema's own narration,
pinned in both directions by consumer-contract.test.ts — a schema bump that
forgets a row, an invented minor, or a row that omits a field its minor narrates
fails pnpm test; a notFields label is a review judgement, as SPEC §7.6
states.
Fixed
orderKeys follow-ups from the #458 dogfood — the pure core seam now warns
(selection/order-key-unknown) when orderKeys is a non-array value
instead of ignoring it silently; .pascorc already rejected it as a config
error, so only direct selectFacts/compile callers see the new warning. The
active-variant interaction the dogfood measured is now reported by the writer
and documented: a variant body is a complete artifact written verbatim, so orderKeys orders the render and does not rewrite it. When the active variant
wins and the slice carries a resolved order, build emits a permanent,
informational note naming the variant and the layer (the body is
authoritative; the order applied to the render) — not a staleness verdict and
not a silent no-op. SPEC §16.2 step 4 owns the mechanical sequence — remove
that platform's active.yaml entry (the other platforms stay), build the
ordered render as the base, let the executing agent compose the body per the
platform skill (the engine models no composition, #476), and re-record with refine --choose <id> --lang <l> — cited from §21.3 rule 11 and §21.6, with an
end-to-end test that runs it and asserts the other platform's choice survives.
Internal
The core seam goes 0.1.3 → 0.1.4 (#458, #462) — two additions to @profile-as-code/core's public surface: orderedForSurface (the one
precedence home for selection.views.<v>.orderKeys) and sameTextAcrossPlatforms with its TextFinding/TextKind types (the
§21.8 advisory detector). The CLI bundles core and is unaffected; the
cohort step skips a version already live on the registry, so an unchanged
0.1.3 would leave the published core describing the previous tree.