Conversation
Maximilian-Nesslauer
left a comment
There was a problem hiding this comment.
Thanks for the RFC draft.
I am not against a namespaced extension point but what I want changed is the motivation, the examples, and three rules that do not hold against the index as it runs today.
Maximilian-Nesslauer
left a comment
There was a problem hiding this comment.
Thanks for the revision.
It addresses all six comments from my first review but the revised proposal exposes several contract problems that the first version did not make visible.
The largest one is the reason for putting consumer-private data into the canonical index at all.
Discussion #37 already puts service-local data in a derived view and makes that view reconstructible from the canonical listing id.
The real ksamods.gg field in KSAModding/content-index#49 is a back-reference to the site's own database record.
Copying that private record id into the canonical listing creates a second copy and a freshness problem instead of removing one.
The Borea accent example also needs a clearer ownership case because it is either Borea-local presentation data or a general author-selected presentation field.
The proposal also needs one answer for pack documents, an exact and computable size rule, and alignment with the existing snapshot contract.
The snapshot already carries every authored document verbatim and does not permit a client to fetch selected authored fields separately.
The schema shape is also already normative in the RFC, so the companion change cannot be left to choose a different shape.
Please also update the pull request title and body.
They still describe the old [metadata] proposal, repeat the old [links] claim, and list issues that the new commit resolved.
| An optional `[extensions]` table on every authored file, holding namespaced key-value data that no resolver, installer, or compatibility check may read. | ||
|
|
||
| It is an extension point, not a field. | ||
| A client or an index puts data under a namespace it owns, every other consumer ignores it, and a key that several consumers converge on becomes a first-class field by RFC. |
There was a problem hiding this comment.
[must fix] The current ownership check, implemented in KSAModding/content-index#34 and described by proposed RFC 0048, does not let a client or an index maintain arbitrary live data in someone else's listing.
Please state who writes and updates an extension. If the consumer owns and changes the value, explain how it stays current without making the content owner submit every consumer-side update.
| ksamods.gg serves its own answer from its own API, Borea keeps a side table, and the same fact exists twice with no way to say which copy is current. | ||
| That is the position the whole of RFC 0031 was written to get out of, reintroduced one layer down. | ||
|
|
||
| Doing nothing does not stop consumers carrying extra data. | ||
| It decides only whether that data lives somewhere with rules, or in private stores nobody else can see. |
There was a problem hiding this comment.
[must fix] This conflicts with the boundary decided in discussion #37.
A derived view keeps service-local data in its own store and keys it by the canonical listing id.
The current field in KSAModding/content-index#49 is ksamods.gg's own database id, so copying it into the canonical listing creates the second copy and a new question about which copy is current.
Please give at least one concrete author-owned fact that must live in the canonical index but has exactly one consumer, or revise the motivation and the Do nothing alternative around the derived-view model we already accepted. Without that evidence, I do not see enough reason to weaken the closed schema.
| In the shared authored core of [RFC 0031](0031-content-metadata-format.md), so it applies to `mod`, `modpack`, `mod-loader`, and every type added later with no per-type work. | ||
| Optional everywhere; absent means nothing. |
There was a problem hiding this comment.
[must fix] Every authored file includes a pack version, but RFC 0031 makes each pack document immutable and the snapshot retains all pack versions.
An extension on a pack is therefore frozen per version, not live, and changing it requires a new pack version. It can also repeat the full allowance once for every version.
Please either exclude modpack, define the data as version-specific for packs, or change the pack model. The current rule conflicts with the live-data reason at line 94.
Changing the pack model might make sense here.
| | Every direct child of `[extensions]` is a table. A scalar or array directly under `[extensions]` makes the file invalid. | Un-namespaced keys are how two consumers end up fighting over `accent`. Forcing the namespace makes a collision impossible rather than unlikely. | | ||
| | Namespace names follow RFC 0031's id rules, compared case-insensitively. | Reusing the id charset means no second naming scheme to specify, and it is already known to be safe on every platform. | | ||
| | A namespace need not be a listed id, and claiming one grants nothing. | The table names consumers, not content, and `borea` is not a mod. | | ||
| | The serialized `[extensions]` table is at most 4 KiB per listing. | Every byte lands in the snapshot RFC 0033 ships to every client, so an unbounded table is a cost paid mostly by people who never read it. | |
There was a problem hiding this comment.
[must fix] Please define the representation that this limit measures and resolve unresolved question 1 before approval.
The TOML source bytes, the parsed JSON value, compact JSON, and the indented snapshot bytes have different sizes, and TOML comments, whitespace.The schema check, snapshot builder, and other implementations need one exact byte sequence and encoding.
|
|
||
| 1. **Is 4 KiB the right cap, and is it per listing or per namespace?** Per listing is simpler and makes namespaces compete for it, which may be the wrong incentive. | ||
| 2. **Should namespaces be registered anywhere?** Unowned is simplest and matches the ecosystem's size; a squatted namespace has no remedy today. | ||
| 3. **How far does the schema open?** Permitting `extensions` with typed namespaces still validates more than permitting a free subtree, and the companion pull request has to pick one. |
There was a problem hiding this comment.
[must fix] This is not an open choice after the Shape and Errors sections.
Those sections require extensions to be a table, each direct child to be a table with a valid id as its name, and case-insensitive duplicates to fail. A companion schema that permits a free subtree at the extensions level would contradict those rules.
Please state the schema boundary here and make the companion pull request implement it, or change the earlier normative rules.
| 1. **Is 4 KiB the right cap, and is it per listing or per namespace?** Per listing is simpler and makes namespaces compete for it, which may be the wrong incentive. | ||
| 2. **Should namespaces be registered anywhere?** Unowned is simplest and matches the ecosystem's size; a squatted namespace has no remedy today. | ||
| 3. **How far does the schema open?** Permitting `extensions` with typed namespaces still validates more than permitting a free subtree, and the companion pull request has to pick one. | ||
| 4. **Does the snapshot carry `[extensions]` for every listing, or may a client fetch it separately?** Small enough not to matter now, but it is the first field whose readers are a strict subset of clients. |
There was a problem hiding this comment.
[must fix] spec/snapshot.md already answers this.
Every authored document appears verbatim in the snapshot, the snapshot is sufficient for offline use, and per-file fetch is only a secondary tooling path. An extensions table therefore appears in the snapshot for every listing and every pack version that carries it.
Please state that result in the reference section and remove this unresolved question. If the proposal instead wants a separate client fetch, it must amend the snapshot contract and explain the loss of its one-fetch and offline guarantees.
It might make sense to reduce the snapshot size? Example calculations if there are any meaningful savings would be nice.
Maximilian-Nesslauer
left a comment
There was a problem hiding this comment.
Thanks for the new revision.
Postponing the proposal is a reasonable outcome but i dont want to dismiss it.
The new text addresses the substance of my previous.
I still request changes because the postponed record is internally inconsistent in some places.
The summary still applies the table to every authored file, while the reference section excludes modpack.
The guide and rules require a consumer to own a namespace, while the same RFC says namespaces are unowned and leaves registration unresolved.
The size rule also does not define how TOML values that have no direct JSON representation are converted, so different implementations can still count different byte sequences.
Finally, the RFC says that none of the postponed design is normative, but the schema section immediately says the rules are normative.
For a postponed RFC, this should use conditional language and state what a future companion change would have to do if the proposal is reopened.
|
|
||
| ## Summary | ||
|
|
||
| An optional `[extensions]` table on every authored file, holding namespaced key-value data that no resolver, installer, or compatibility check may read. |
There was a problem hiding this comment.
[must fix] The summary still says every authored file, but the reference section limits the table to mod and mod-loader and explicitly excludes modpack.
Please use the same scope here. Also, RFC 0031 defines the shared authored core as the fields carried by every authored document, so line 89 should not call a field that excludes packs part of that shared core.
| Each direct child of `[extensions]` is a namespace named after the consumer that owns it. | ||
| That consumer reads its own namespace and ignores every other; a client that knows none of them loses nothing. |
There was a problem hiding this comment.
[must fix] The design cannot require a namespace owner while it also states that namespaces are unowned.
This paragraph and line 117 require a consumer that owns the namespace, but line 103 says that claiming a name grants nothing, line 144 calls namespaces unowned, and unresolved question 3 leaves registration open.
Please either define how a consumer owns a namespace or replace the ownership rule with a rule that does not need an owner, such as a consumer reading only a namespace that it explicitly recognizes.
| One representation, so the schema check, the snapshot builder and any other implementation compute the same number: | ||
|
|
||
| **The UTF-8 byte length of the parsed `extensions` value serialized as compact JSON, with no insignificant whitespace.** | ||
|
|
||
| TOML comments, indentation, and key order do not count, and neither does the two-space indentation `spec/snapshot.md` applies when the value reaches the snapshot. | ||
| Whether 4 KiB is the right number, and whether it should be per listing or per namespace, was never settled; per listing is simpler and makes namespaces compete for the allowance, which may be the wrong incentive. |
There was a problem hiding this comment.
[must fix]
TOML includes date and time values and special floating-point values that have no direct JSON representation, and compact JSON does not define one canonical conversion and serialization for all implementations.
Please define the TOML-to-JSON value mapping and a canonical serialization, restrict extension values to a specified JSON-compatible subset, or record the measurement as unresolved.
| ### The schema is part of this RFC, not left open | ||
|
|
||
| The rules above are normative, so the companion pull request against `KSAModding/content-index` implements exactly them and has no latitude to permit a free subtree at `extensions`: a table, each direct child a table, each name a valid id, case-insensitive duplicates rejected, and the size rule as measured above. | ||
| Without that change the field is rejected at publish time regardless of what this RFC says, the way RFC 0048 depends on [content-index#34](https://github.com/KSAModding/content-index/pull/34). |
There was a problem hiding this comment.
[must fix] This section conflicts with line 85 and with the current repository state.
A Postponed RFC is non-normative, and there is no companion pull request for extensions in KSAModding/content-index yet, but this paragraph says the rules are normative and that the companion pull request implements them.
Please use conditional wording, such as If this RFC is reopened, a companion pull request must implement these rules, and make the same correction in the pull request body.
What
Proposed an optional
[extensions]table on authored files: namespaced key-value data no resolver, installer, or compatibility check may read.Now postponed. Review established that the derived-view model accepted in #37 already covers every case this could name, and nobody could produce the one kind of fact the table would be needed for. The corrected design stays in the file so a future proposal starts from it rather than from this one's first draft.
RFC checklist
rfc:field in the front matterDECISIONS.mdupdated,status: Accepted, and any superseded RFC markedPostponedis terminal, so this can merge; onlyAcceptedtakes aDECISIONS.mdrow. The third box is vacuous — this RFC makes no claim about game behavior, which was always the point.What the latest commit resolved
Six [must fix] items from @Maximilian-Nesslauer's review, and the two that led to postponing:
ksamods-ggfield in content-index#49 is a back-reference to that site's own database record, so copying it in creates the second copy and a freshness problem, andaccentnever had a clear owner at all.modpackwas the smallest of the three ways out.extensionsvalue serialized as compact JSON, no insignificant whitespace. TOML comments, indentation, key order and the snapshot's two-space indent do not count.spec/snapshot.mdalready answers it: every authored document appears verbatim and is sufficient offline, so the table appears there for every listing carrying one. A separate fetch would have to amend that contract and give up its one-fetch and offline guarantees.Also from the first review round: the table is
[extensions], not[metadata], since the whole file is metadata; the closed-schema starting position replaced the wrong[links]claim; and the icon/banner example is gone, since those are wanted by every client and belong to #45.The filename still says
listing-metadataso the review threads stay attached — rename at merge if you want the slug to match.🤖 Generated with Claude Code