What This Blog Is About
UNSW IT Student, Sydney, Australia. This is just a place for me to write down things I’ve been thinking / feeling about.
Agentic coding tools like Claude Code allow even people with no engineering background to turn ideas into working software in an afternoon.
I’m reminded of an analogy. Bitcoin leverages what individuals can contribute, transforming idle computing resources into a decentralized, consistently incentivized network. Could such a network exist in the software world, where individuals can contribute AI-generated applications or modules and receive rewards?
I’ve done some preliminary research on this idea, and it turns out it’s largely unworkable.
Several real-world projects are exploring this area. Infinity Ground is the clearest example: it’s an agentic IDE, and “Vibe Coders” can generate deployable, on-chain decentralized applications while supporting template remixing and token rewards for contributors.
Classifying it as a DePIN (Decentralized Physical Infrastructure Network—similar to Helium, Filecoin, and Render) is a misconception. DePIN works because its contributions involve verifiable physical resources, such as the actual number of bytes stored or the actual GPU hours used for computation. The blockchain’s role in the DePIN network is simply to record proof-of-work, process payments, and distribute rewards.
Vibe-coding-on-chain platforms don’t have that. What’s being contributed is code only and there’s no objective way to verify “this contribution has value.” That distinction is the whole ballgame.
The core of DePIN is shifting the question “Is this contribution valuable?” to “Did the manual work actually happen?”. Storage proofs and coverage proofs are things that can be verified cryptographically.
There’s no direct equivalent to “This AI-generated application is good.” If you reward “releases,” you’ll receive a flood of effortless, mass-generated templates. If you try to directly reward “quality,” you revert to a state requiring human judgment, making decentralization difficult.
The fix I found is: don’t reward releases, reward actual use. That is, reward the module only when it’s actually called at runtime—whether by a paying end-user using the application or another AI agent calling it a dependency in a multi-agent workflow. Each call triggers a small payment that automatically flows up the genealogy to every upstream contributor whose code actually depends on it, much like streaming royalties. This is called Proof of Invocation: the verification shifts from “Is this creative work good?” (subjective) to “Did a real payment event occur, and can we track who it should have gone to?” (objective), which is exactly the problem that blockchain aims to solve.
We all use npm packages, and their usefulness stems from the fact that calling them is free. A network that charges for calls will compete with it and is destined to fail in the cold start phase from the outset: any developer aiming for maximum user reach will continue to release for free, and only those seeking direct royalty income will choose a paid network. This makes it structurally closer to an AppStore.
Another fairness issue deserves attention: LLMs are trained on the unpaid labor of decades of open-source software, whose original authors have never received any compensation. A Proof-of-Invocation networks essentially charge downstream users who generate AI code, not the model companies that capture upstream value during training. The people who should truly bear the responsibility are not paying this fee.
Leaving aside the token economics aspect, one part remains highly practical: multi-agent systems require a per-request payment method. The open protocol x402, jointly launched by Coinbase and Cloudflare, revives the long-dormant HTTP 402 “Payment Required” status code: an agent requests paid resources, the server responds with a 402 status code along with payment terms, the agent signs a stablecoin micropayment agreement, and retryes the request. No account or manual approval is required; settlement is completed in a single HTTP round trip.
Any Proof of Invocation-style system needs to be built upon this layer. An interesting design question is, “Given that agents can already pay each other per invocation, how do we fairly and automatically distribute this reward to all contributors of the code that the invocation actually depends on?”
Understanding which code a piece of AI-generated code actually depends on can now be built into the existing tool usage loop of coding agents. When the agent generates code, it knows exactly which resources it used at that moment: which files it read, which external modules or templates it extracted from, and which prompt produced which output. Attaching this information as structured metadata to the commit history is a simple engineering problem, not a research problem. The output resembles a Software Bill of Materials (SBOM), but it’s automatically generated while the code is being written, not rebuilt afterward.
Now, with the increasing amount of AI-generated code, we increasingly need to answer the question, “Where did this code come from? Can we trust it?”, and most current AI coding tools fail to provide satisfactory answers. For a team that doesn’t yet rely on any external payment networks, having a built-in code attribution layer in the coding agent is highly useful from the start.
This is the part that has to exist first, regardless of what gets built on top of it. You cannot fairly split a payment across a dependency chain — via x402 or anything else — if you never recorded the dependency chain in the first place. Attribution is the prerequisite; payment is the optional feature you can bolt on later once the attribution data is trustworthy enough to route money against.
In a decimal system, any two-digit number can be represented as a first-order polynomial where x=10:
N = 10a + b, P(x) = ax + b
Where a is the tens-place coefficient and b is the units-place coefficient.
When calculating the square of this number, it is equivalent to the binomial expansion of the polynomial:
P(x)^2 = (ax + b)^2 = a^2x^2 + 2abx + b^2
In pure algebra, the coefficients a^2, 2ab, and b^2 are independent. However, in decimal arithmetic, if a coefficient exceeds the base 10, a carrying operation is triggered.
Take 13^2 as an example, where a=1, b=3:
1 | - a^2 = 1^2 = 1 |
Take 25^2 as an example, where a=2, b=5:
1 | - a^2 = 4, \quad 2ab = 20, \quad b^2 = 25 |
Arithmetic operations in positional notation are essentially evaluations of polynomials at x=10. This discovery reveals the isomorphism between the Place-Value Principle and Algebraic Expansion.
Abstract: This report aims to introduce a methodology for robustly extracting structured data from Excel, containing multi-layer headers by using pandas(Python) only. And in the end the weakness of this method will be shown.
Normally, an Excel table is composed by couples of header lines and data lines. For a multi-layer headers table, the header may looks like this:
And in pandas’ view, it looks like that(N for nan):
1 | a b N N c |
The purpose is extracting headers from whole table.
Assuming 1:
We are able to find the start of the header. Maybe line 0 or maybe some filters can be used.
Assuming 2:
The values in first line of data block must be different to the last line of header block.
In each line, we are trying to find if next line is valid header. Let A, B to be current line and next line. And let S to be a statue of judging wether current value is a potential merge cell.
Firstly, find the right value of Ai, if Ai is not nan, Ai+1 is not nan, it means Ai absolutely is not a merge cell, like a in my example. Set s = False
If Ai is not nan and Ai+1 is nan, it means we can consider Ai as a potential merge cell, like b, b1, b2, b1.2. Set s = True.
Secondly, another judging should be done. If s = True, it means the value below it can be anything, like b1 != b, b1.1 != b1.
If s = False, if Bi is nan, it is valid for next line is table, like Ai = a; Bi = N.
If s = False, if Bi != nan and Ai != Bi, as Assuming 2, it means B is not header anymore. So we can say the last line of header is A.
1 | def is_valid(upper, lower): |
The biggest problem would be the situation like Ai = b1.2. In this circumstance, Ai would be recognised as a potential merge cell, but actually the Ai+1 = N is belongs to b2.
Two steps determine
permissions table: Only determine whether this role can perform basic operations, such as Viewers can Read, but can not Write.policies table: Determine whether the operation of this role is constrained, if it passes the RBAC judgment. For example, if this role is Viewer, then determine whether the knowledge base is public. If it is not, determine whether it is a departmental knowledge base. If it is, determine whether the user’s department is the same as the knowledge base department attribute, or whether it is used to handle dynamically changing attributes (IP, timestamp)Role inheritance
parent_id column in the roles table, sourced from users.id, to establish a hierarchical relationship among rolesTemporary Permissions
role with a validity period of only one month.start_time and end_time fields to the user_roles table.Multi-team consideration
team table, and all core tables must include a team_id column. If users from TeamA and TeamB create the same entity (e.g., role, policy), the entity must have a clear ownership marker to ensure data isolationUser-Item Many-to-Many Relationship
projects table needs to be maintained, which is associated with the users tableData analysis
logs for future design, which is associated with users, serving as the foundation for user personas, tagging systems, and OLAP layered construction
Assuming the resource subject to access control is a knowledge base, which includes: a public knowledge base (accessible to everyone for read), and a departmental database (accessible only to personnel of the department for read, and only to certain roles for write)
After logging in, user rocky (role: editor; department: R&D Department) attempts to edit the R&D Department document in the department knowledge base. The application code first queries the roles table to find the associated roles (which may be multiple)
1 | SELECT role_id FROM user_roles WHERE user_id = 1; |
Starting from the direct role 101, recursively obtain all inherited roles through parent_id. Assume that 101 fully encompasses the permissions of 102
1 | -- Recursive function |
Query the permissions table and first find all static rules related to rocky
1 | SELECT p.permission_code |
It indicates that the basic read-write function of the knowledge base is available. At this point, the RBAC check has been passed, and the application code can return a user JSON, such as {user: 1, role: [101, 102], department: R&D Department, perm: [read, write] ... }
However, further judgment is needed to determine whether Rocky has write permission for the R&D department documents in one of the departmental knowledge bases. In this case, ABAC is introduced
Query the “policies” table using the code, and extract the “resources” JSON from “policy_document”, where {type: department, department: Development .. }It indicates that the documentrocky` intends to write is for the departmental knowledge base of the R&D department
1 | SELECT p.policy_document |
Among all the identified policies, compare the parsed resources json and user json. If user.attributes.department == 'Development' and "resource.type": "department", then the document can be edited
For the maintenance of the role_policies table, for the same role chain, it is generally only necessary to insert the (role, policy) pair for the lowest-level role, Viewer
To maintain the ‘role_permissions’ table, simply insert the newly added permissions at a higher level
1 | (3, 10), -- Viewer: read |
Abstract: This report aims to analyze a specific type of integer sequence and derive all possible hierarchical structures for it. The core of the problem is to reconstruct the implicit, nested tree-like hierarchy from a flat, one-dimensional sequence representing heading numbers. The report specifies the constraints for this problem and provides a complete algorithm capable of finding all possible solutions. The analysis shows that multiple valid solutions may exist, classifying the problem as a Constraint Satisfaction Problem (CSP), which can be systematically solved using a backtracking algorithm.
Given an article that uses a consistent numbering format for its sections, how can we reconstruct its implicit tree-like hierarchical structure?
For example, given a sequence like:
1 | 1 xx |
This can be abstracted as follows: given a sequence of positive integers (e.g., [1, 2, 1, 2, 3, 1, 2, 3, 4, 3]), we need to assign a level to each number in the sequence. This level is also represented by a sequence of positive integers, indicating its depth in the document structure (e.g., level-1 heading, level-2 heading, etc.). For instance, [1, 1, 2, 2, 2, 3, 3, 3, 2, 1] and [1, 1, 2, 2, 2, 3, 3, 3, 3, 1] are both valid solutions.
We have determined that a valid hierarchical structure must adhere to the following complete set of constraint rules:
Starting Rule: The first number in the sequence must be 1, and its level is fixed at 1.
Headings Start with 1: If a number in the sequence is 1, its level must be one greater than the level of the preceding number (i.e., level_of_prev + 1).
Level Rule for Non-1s: For any number n > 1 in the sequence, its level L can be any integer such that 1 <= L <= L_prev, where L_prev is the level of the preceding number.
Same-Level Order Rule: At any given level, the heading numbers must appear in a strictly and sequentially increasing order. For example, a sequence of level-2 headings can be 1, 2, 3, but not 1, 3 or 1, 2, 2.
Goal: To find and list all possible level assignment schemes that satisfy all the above rules.
This problem can be precisely modeled as a Constraint Satisfaction Problem (CSP).
A CSP consists of three core components:
Variables: The unknowns we need to solve for. In this problem, the variables are the levels of each number in the sequence, which can be represented as a set {L_0, L_1, ..., L_{n-1}}, where L_i is the level of the i-th number in the sequence.
Domains: The possible values for each variable.
For L_0, the domain is {1}.
For L_i (where i > 0):
If sequence[i] == 1, its domain is {L_{i-1} + 1}.
If sequence[i] > 1, its domain is {1, 2, ..., L_{i-1}}.
Constraints: The relationships that must hold between the variables. These are the global rules we defined in the problem description, especially the “Same-Level Order Rule.” A formal constraint can be described as: “For any two indices i < j, if their levels are the same (L_i = L_j) and there are no other elements with the same level between them, then it must be that sequence[j] == sequence[i] + 1.”
A common and powerful method for solving CSPs is the Backtracking Algorithm. This algorithm systematically explores all possible solutions using a depth-first search (DFS) approach.
The sole reason for the existence of multiple solutions is as follows: when the algorithm processes a number that is not ‘1’, there are at least two or more theoretically possible levels it could be assigned to, both of which simultaneously satisfy the global “Same-Level Order Rule.”
This occurs when a number meets the following conditions:
It must be a number other than 1 in the sequence; let’s call it X.
When processing X, the level of the preceding number, L_prev, must be greater than or equal to 2. This provides at least two theoretical level choices for X (e.g., level 1 and level 2). If L_prev were 1, X‘s only possible choice would be level 1, creating no branching.
There are multiple valid “parents.” In the sequence preceding X, there must exist at least two different levels whose last number was X-1.
“Parent A”: There exists a level L_A whose last number was X-1.
“Parent B”: There also exists a different level L_B (L_B != L_A) whose last number was also X-1.
Furthermore, both L_A and L_B must be within X‘s range of possible levels (i.e., both must be less than or equal to L_prev).
1 | def find_all_structures(sequence): |